mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-08 04:03:48 +02:00
Fix sharing password. fixes #744
This commit is contained in:
parent
16bf756582
commit
ba9b5292e1
@ -1,5 +1,5 @@
|
|||||||
import {NextFunction, Request, Response} from 'express';
|
import {NextFunction, Request, Response} from 'express';
|
||||||
import {CreateSharingDTO, SharingDTO} from '../../common/entities/SharingDTO';
|
import {CreateSharingDTO, SharingDTO, SharingDTOKey} from '../../common/entities/SharingDTO';
|
||||||
import {ObjectManagers} from '../model/ObjectManagers';
|
import {ObjectManagers} from '../model/ObjectManagers';
|
||||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||||
import {Config} from '../../common/config/private/Config';
|
import {Config} from '../../common/config/private/Config';
|
||||||
@ -9,9 +9,9 @@ import {UserRoles} from '../../common/entities/UserDTO';
|
|||||||
|
|
||||||
export class SharingMWs {
|
export class SharingMWs {
|
||||||
public static async getSharing(
|
public static async getSharing(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
@ -20,36 +20,69 @@ export class SharingMWs {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.findOne(sharingKey);
|
await ObjectManagers.getInstance().SharingManager.findOne(sharingKey);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during retrieving sharing link',
|
'Error during retrieving sharing link',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getSharingKey(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
): Promise<void> {
|
||||||
|
if (Config.Sharing.enabled === false) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
const sharingKey = req.params[QueryParams.gallery.sharingKey_params];
|
||||||
|
|
||||||
|
try {
|
||||||
|
req.resultPipe =
|
||||||
|
{sharingKey: (await ObjectManagers.getInstance().SharingManager.findOne(sharingKey)).sharingKey} as SharingDTOKey;
|
||||||
|
return next();
|
||||||
|
} catch (err) {
|
||||||
|
return next(
|
||||||
|
new ErrorDTO(
|
||||||
|
ErrorCodes.GENERAL_ERROR,
|
||||||
|
'Error during retrieving sharing key',
|
||||||
|
err
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async createSharing(
|
public static async createSharing(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
typeof req.body === 'undefined' ||
|
typeof req.body === 'undefined' ||
|
||||||
typeof req.body.createSharing === 'undefined'
|
typeof req.body.createSharing === 'undefined'
|
||||||
) {
|
) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'createSharing filed is missing')
|
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'createSharing filed is missing')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const createSharing: CreateSharingDTO = req.body.createSharing;
|
const createSharing: CreateSharingDTO = req.body.createSharing;
|
||||||
|
|
||||||
|
if (Config.Sharing.passwordRequired && !createSharing.password) {
|
||||||
|
|
||||||
|
return next(
|
||||||
|
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'Password is required.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let sharingKey = SharingMWs.generateKey();
|
let sharingKey = SharingMWs.generateKey();
|
||||||
|
|
||||||
// create one not yet used
|
// create one not yet used
|
||||||
@ -71,45 +104,45 @@ export class SharingMWs {
|
|||||||
password: createSharing.password,
|
password: createSharing.password,
|
||||||
creator: req.session['user'],
|
creator: req.session['user'],
|
||||||
expires:
|
expires:
|
||||||
createSharing.valid >= 0 // if === -1 its forever
|
createSharing.valid >= 0 // if === -1 its forever
|
||||||
? Date.now() + createSharing.valid
|
? Date.now() + createSharing.valid
|
||||||
: new Date(9999, 0, 1).getTime(), // never expire
|
: new Date(9999, 0, 1).getTime(), // never expire
|
||||||
includeSubfolders: createSharing.includeSubfolders,
|
includeSubfolders: createSharing.includeSubfolders,
|
||||||
timeStamp: Date.now(),
|
timeStamp: Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.createSharing(
|
await ObjectManagers.getInstance().SharingManager.createSharing(
|
||||||
sharing
|
sharing
|
||||||
);
|
);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during creating sharing link',
|
'Error during creating sharing link',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async updateSharing(
|
public static async updateSharing(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
typeof req.body === 'undefined' ||
|
typeof req.body === 'undefined' ||
|
||||||
typeof req.body.updateSharing === 'undefined'
|
typeof req.body.updateSharing === 'undefined'
|
||||||
) {
|
) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'updateSharing filed is missing')
|
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'updateSharing filed is missing')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const updateSharing: CreateSharingDTO = req.body.updateSharing;
|
const updateSharing: CreateSharingDTO = req.body.updateSharing;
|
||||||
@ -119,14 +152,14 @@ export class SharingMWs {
|
|||||||
path: directoryName,
|
path: directoryName,
|
||||||
sharingKey: '',
|
sharingKey: '',
|
||||||
password:
|
password:
|
||||||
updateSharing.password && updateSharing.password !== ''
|
updateSharing.password && updateSharing.password !== ''
|
||||||
? updateSharing.password
|
? updateSharing.password
|
||||||
: null,
|
: null,
|
||||||
creator: req.session['user'],
|
creator: req.session['user'],
|
||||||
expires:
|
expires:
|
||||||
updateSharing.valid >= 0 // if === -1 its forever
|
updateSharing.valid >= 0 // if === -1 its forever
|
||||||
? Date.now() + updateSharing.valid
|
? Date.now() + updateSharing.valid
|
||||||
: new Date(9999, 0, 1).getTime(), // never expire
|
: new Date(9999, 0, 1).getTime(), // never expire
|
||||||
includeSubfolders: updateSharing.includeSubfolders,
|
includeSubfolders: updateSharing.includeSubfolders,
|
||||||
timeStamp: Date.now(),
|
timeStamp: Date.now(),
|
||||||
};
|
};
|
||||||
@ -134,36 +167,37 @@ export class SharingMWs {
|
|||||||
try {
|
try {
|
||||||
const forceUpdate = req.session['user'].role >= UserRoles.Admin;
|
const forceUpdate = req.session['user'].role >= UserRoles.Admin;
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.updateSharing(
|
await ObjectManagers.getInstance().SharingManager.updateSharing(
|
||||||
sharing,
|
sharing,
|
||||||
forceUpdate
|
forceUpdate
|
||||||
);
|
);
|
||||||
|
console.log(req.resultPipe);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during updating sharing link',
|
'Error during updating sharing link',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async deleteSharing(
|
public static async deleteSharing(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
typeof req.params === 'undefined' ||
|
typeof req.params === 'undefined' ||
|
||||||
typeof req.params['sharingKey'] === 'undefined'
|
typeof req.params['sharingKey'] === 'undefined'
|
||||||
) {
|
) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'sharingKey is missing')
|
new ErrorDTO(ErrorCodes.INPUT_ERROR, 'sharingKey is missing')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const sharingKey: string = req.params['sharingKey'];
|
const sharingKey: string = req.params['sharingKey'];
|
||||||
@ -177,49 +211,49 @@ export class SharingMWs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.deleteSharing(
|
await ObjectManagers.getInstance().SharingManager.deleteSharing(
|
||||||
sharingKey
|
sharingKey
|
||||||
);
|
);
|
||||||
req.resultPipe = 'ok';
|
req.resultPipe = 'ok';
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during deleting sharing',
|
'Error during deleting sharing',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async listSharing(
|
public static async listSharing(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.listAll();
|
await ObjectManagers.getInstance().SharingManager.listAll();
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during listing shares',
|
'Error during listing shares',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async listSharingForDir(
|
public static async listSharingForDir(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Config.Sharing.enabled === false) {
|
if (Config.Sharing.enabled === false) {
|
||||||
return next();
|
return next();
|
||||||
@ -229,19 +263,19 @@ export class SharingMWs {
|
|||||||
try {
|
try {
|
||||||
if (req.session['user'].role >= UserRoles.Admin) {
|
if (req.session['user'].role >= UserRoles.Admin) {
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.listAllForDir(dir);
|
await ObjectManagers.getInstance().SharingManager.listAllForDir(dir);
|
||||||
} else {
|
} else {
|
||||||
req.resultPipe =
|
req.resultPipe =
|
||||||
await ObjectManagers.getInstance().SharingManager.listAllForDir(dir, req.session['user']);
|
await ObjectManagers.getInstance().SharingManager.listAllForDir(dir, req.session['user']);
|
||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(
|
return next(
|
||||||
new ErrorDTO(
|
new ErrorDTO(
|
||||||
ErrorCodes.GENERAL_ERROR,
|
ErrorCodes.GENERAL_ERROR,
|
||||||
'Error during listing shares',
|
'Error during listing shares',
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,8 +283,8 @@ export class SharingMWs {
|
|||||||
private static generateKey(): string {
|
private static generateKey(): string {
|
||||||
function s4(): string {
|
function s4(): string {
|
||||||
return Math.floor((1 + Math.random()) * 0x10000)
|
return Math.floor((1 + Math.random()) * 0x10000)
|
||||||
.toString(16)
|
.toString(16)
|
||||||
.substring(1);
|
.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s4() + s4();
|
return s4() + s4();
|
||||||
|
@ -156,8 +156,8 @@ export class AuthenticationMWs {
|
|||||||
if (
|
if (
|
||||||
!sharing ||
|
!sharing ||
|
||||||
sharing.expires < Date.now() ||
|
sharing.expires < Date.now() ||
|
||||||
(Config.Sharing.passwordProtected === true &&
|
((Config.Sharing.passwordRequired === true ||
|
||||||
sharing.password &&
|
sharing.password) &&
|
||||||
!PasswordHelper.comparePassword(password, sharing.password))
|
!PasswordHelper.comparePassword(password, sharing.password))
|
||||||
) {
|
) {
|
||||||
Logger.warn(LOG_TAG, 'Failed login with sharing:' + sharing.sharingKey + ', bad password');
|
Logger.warn(LOG_TAG, 'Failed login with sharing:' + sharing.sharingKey + ', bad password');
|
||||||
@ -265,8 +265,9 @@ export class AuthenticationMWs {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no 'free login' if passwords are required, or it is set
|
||||||
if (
|
if (
|
||||||
Config.Sharing.passwordProtected === true &&
|
Config.Sharing.passwordRequired === true ||
|
||||||
sharing.password
|
sharing.password
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,6 +11,7 @@ export class SharingRouter {
|
|||||||
public static route(app: express.Express): void {
|
public static route(app: express.Express): void {
|
||||||
this.addShareLogin(app);
|
this.addShareLogin(app);
|
||||||
this.addGetSharing(app);
|
this.addGetSharing(app);
|
||||||
|
this.addGetSharingKey(app);
|
||||||
this.addCreateSharing(app);
|
this.addCreateSharing(app);
|
||||||
this.addUpdateSharing(app);
|
this.addUpdateSharing(app);
|
||||||
this.addListSharing(app);
|
this.addListSharing(app);
|
||||||
@ -20,79 +21,94 @@ export class SharingRouter {
|
|||||||
|
|
||||||
private static addShareLogin(app: express.Express): void {
|
private static addShareLogin(app: express.Express): void {
|
||||||
app.post(
|
app.post(
|
||||||
Config.Server.apiPath + '/share/login',
|
Config.Server.apiPath + '/share/login',
|
||||||
AuthenticationMWs.inverseAuthenticate,
|
AuthenticationMWs.inverseAuthenticate,
|
||||||
AuthenticationMWs.shareLogin,
|
AuthenticationMWs.shareLogin,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSessionUser
|
RenderingMWs.renderSessionUser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to check the key validity
|
||||||
|
* @param app
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private static addGetSharingKey(app: express.Express): void {
|
||||||
|
app.get(
|
||||||
|
Config.Server.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params + '/key',
|
||||||
|
// its a public path
|
||||||
|
SharingMWs.getSharingKey,
|
||||||
|
ServerTimingMWs.addServerTiming,
|
||||||
|
RenderingMWs.renderSharing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addGetSharing(app: express.Express): void {
|
private static addGetSharing(app: express.Express): void {
|
||||||
app.get(
|
app.get(
|
||||||
Config.Server.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params,
|
Config.Server.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params,
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.LimitedGuest),
|
AuthenticationMWs.authorise(UserRoles.LimitedGuest),
|
||||||
SharingMWs.getSharing,
|
SharingMWs.getSharing,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSharing
|
RenderingMWs.renderSharing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addCreateSharing(app: express.Express): void {
|
private static addCreateSharing(app: express.Express): void {
|
||||||
app.post(
|
app.post(
|
||||||
[Config.Server.apiPath + '/share/:directory(*)', Config.Server.apiPath + '/share/', Config.Server.apiPath + '/share//'],
|
[Config.Server.apiPath + '/share/:directory(*)', Config.Server.apiPath + '/share/', Config.Server.apiPath + '/share//'],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.User),
|
AuthenticationMWs.authorise(UserRoles.User),
|
||||||
SharingMWs.createSharing,
|
SharingMWs.createSharing,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSharing
|
RenderingMWs.renderSharing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addUpdateSharing(app: express.Express): void {
|
private static addUpdateSharing(app: express.Express): void {
|
||||||
app.put(
|
app.put(
|
||||||
[Config.Server.apiPath + '/share/:directory(*)', Config.Server.apiPath + '/share/', Config.Server.apiPath + '/share//'],
|
[Config.Server.apiPath + '/share/:directory(*)', Config.Server.apiPath + '/share/', Config.Server.apiPath + '/share//'],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.User),
|
AuthenticationMWs.authorise(UserRoles.User),
|
||||||
SharingMWs.updateSharing,
|
SharingMWs.updateSharing,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSharing
|
RenderingMWs.renderSharing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addDeleteSharing(app: express.Express): void {
|
private static addDeleteSharing(app: express.Express): void {
|
||||||
app.delete(
|
app.delete(
|
||||||
[Config.Server.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params],
|
[Config.Server.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.User),
|
AuthenticationMWs.authorise(UserRoles.User),
|
||||||
SharingMWs.deleteSharing,
|
SharingMWs.deleteSharing,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderResult
|
RenderingMWs.renderResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addListSharing(app: express.Express): void {
|
private static addListSharing(app: express.Express): void {
|
||||||
app.get(
|
app.get(
|
||||||
[Config.Server.apiPath + '/share/listAll'],
|
[Config.Server.apiPath + '/share/listAll'],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||||
SharingMWs.listSharing,
|
SharingMWs.listSharing,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSharingList
|
RenderingMWs.renderSharingList
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addListSharingForDir(app: express.Express): void {
|
private static addListSharingForDir(app: express.Express): void {
|
||||||
app.get(
|
app.get(
|
||||||
[Config.Server.apiPath + '/share/list/:directory(*)',
|
[Config.Server.apiPath + '/share/list/:directory(*)',
|
||||||
Config.Server.apiPath + '/share/list//',
|
Config.Server.apiPath + '/share/list//',
|
||||||
Config.Server.apiPath + '/share/list'],
|
Config.Server.apiPath + '/share/list'],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.User),
|
AuthenticationMWs.authorise(UserRoles.User),
|
||||||
SharingMWs.listSharingForDir,
|
SharingMWs.listSharingForDir,
|
||||||
ServerTimingMWs.addServerTiming,
|
ServerTimingMWs.addServerTiming,
|
||||||
RenderingMWs.renderSharingList
|
RenderingMWs.renderSharingList
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,12 +273,12 @@ export class ClientSharingConfig {
|
|||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
tags:
|
tags:
|
||||||
{
|
{
|
||||||
name: $localize`Password protected`,
|
name: $localize`Require password`,
|
||||||
priority: ConfigPriority.advanced
|
priority: ConfigPriority.advanced
|
||||||
},
|
},
|
||||||
description: $localize`Enables password protected sharing links.`,
|
description: $localize`Requires password protected sharing links.`,
|
||||||
})
|
})
|
||||||
passwordProtected: boolean = true;
|
passwordRequired: boolean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubConfigClass({tags: {client: true}, softReadonly: true})
|
@SubConfigClass({tags: {client: true}, softReadonly: true})
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import {UserDTO} from './UserDTO';
|
import {UserDTO} from './UserDTO';
|
||||||
|
|
||||||
export interface SharingDTO {
|
export interface SharingDTOKey {
|
||||||
|
sharingKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SharingDTO extends SharingDTOKey {
|
||||||
id: number;
|
id: number;
|
||||||
path: string;
|
path: string;
|
||||||
sharingKey: string;
|
sharingKey: string;
|
||||||
|
@ -65,16 +65,16 @@
|
|||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<div class="btn-group" dropdown #dropdown="bs-dropdown" placement="bottom"
|
<div class="btn-group" dropdown #dropdown="bs-dropdown" placement="bottom"
|
||||||
[autoClose]="false" container="body">
|
[autoClose]="false" container="body">
|
||||||
<button id="button-alignment" dropdownToggle
|
<button id="button-frame-menu" dropdownToggle
|
||||||
type="button" class="btn btn-tertiary dropdown-toggle"
|
type="button" class="btn btn-tertiary dropdown-toggle"
|
||||||
aria-controls="dropdown-alignment">
|
aria-controls="dropdown-frame-menu">
|
||||||
<ng-icon class="align-text-top" size="1.2em" name="ionMenuOutline"></ng-icon>
|
<ng-icon class="align-text-top" size="1.2em" name="ionMenuOutline"></ng-icon>
|
||||||
<span *ngIf="isAdmin() && notificationService.numberOfNotifications>0"
|
<span *ngIf="isAdmin() && notificationService.numberOfNotifications>0"
|
||||||
class="navbar-badge badge text-bg-warning">{{notificationService.numberOfNotifications}}</span>
|
class="navbar-badge badge text-bg-warning">{{notificationService.numberOfNotifications}}</span>
|
||||||
</button>
|
</button>
|
||||||
<ul id="dropdown-alignment" *dropdownMenu
|
<ul id="dropdown-frame-menu" *dropdownMenu
|
||||||
class="dropdown-menu dropdown-menu-right"
|
class="dropdown-menu dropdown-menu-right"
|
||||||
role="menu" aria-labelledby="button-alignment">
|
role="menu" aria-labelledby="button-frame-menu">
|
||||||
|
|
||||||
<li role="menuitem" class="d-xl-none">
|
<li role="menuitem" class="d-xl-none">
|
||||||
<div style="white-space: nowrap;" class="dropdown-item">
|
<div style="white-space: nowrap;" class="dropdown-item">
|
||||||
|
@ -52,18 +52,18 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public contentLoader: ContentLoaderService,
|
public contentLoader: ContentLoaderService,
|
||||||
public galleryService: ContentService,
|
public galleryService: ContentService,
|
||||||
private authService: AuthenticationService,
|
private authService: AuthenticationService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private shareService: ShareService,
|
private shareService: ShareService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private navigation: NavigationService,
|
private navigation: NavigationService,
|
||||||
private filterService: FilterService,
|
private filterService: FilterService,
|
||||||
private sortingService: GallerySortingService,
|
private sortingService: GallerySortingService,
|
||||||
private piTitleService: PiTitleService,
|
private piTitleService: PiTitleService,
|
||||||
private gpxFilesFilterPipe: GPXFilesFilterPipe,
|
private gpxFilesFilterPipe: GPXFilesFilterPipe,
|
||||||
private mdFilesFilterPipe: MDFilesFilterPipe,
|
private mdFilesFilterPipe: MDFilesFilterPipe,
|
||||||
) {
|
) {
|
||||||
this.mapEnabled = Config.Map.enabled;
|
this.mapEnabled = Config.Map.enabled;
|
||||||
PageHelper.showScrollY();
|
PageHelper.showScrollY();
|
||||||
@ -79,17 +79,17 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
// if the timer is longer than 10 years, just do not show it
|
// if the timer is longer than 10 years, just do not show it
|
||||||
if (
|
if (
|
||||||
(this.shareService.sharingSubject.value.expires - Date.now()) /
|
(this.shareService.sharingSubject.value.expires - Date.now()) /
|
||||||
1000 /
|
1000 /
|
||||||
86400 /
|
86400 /
|
||||||
365 >
|
365 >
|
||||||
10
|
10
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = Math.floor(
|
t = Math.floor(
|
||||||
(this.shareService.sharingSubject.value.expires - Date.now()) / 1000
|
(this.shareService.sharingSubject.value.expires - Date.now()) / 1000
|
||||||
);
|
);
|
||||||
this.countDown = {} as any;
|
this.countDown = {} as any;
|
||||||
this.countDown.day = Math.floor(t / 86400);
|
this.countDown.day = Math.floor(t / 86400);
|
||||||
@ -118,31 +118,26 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
async ngOnInit(): Promise<boolean> {
|
async ngOnInit(): Promise<boolean> {
|
||||||
await this.shareService.wait();
|
await this.shareService.wait();
|
||||||
if (
|
if (!this.authService.isAuthenticated()) {
|
||||||
!this.authService.isAuthenticated() &&
|
|
||||||
(!this.shareService.isSharing() ||
|
|
||||||
(this.shareService.isSharing() &&
|
|
||||||
Config.Sharing.passwordProtected === true))
|
|
||||||
) {
|
|
||||||
return this.navigation.toLogin();
|
return this.navigation.toLogin();
|
||||||
}
|
}
|
||||||
this.showSearchBar = this.authService.canSearch();
|
this.showSearchBar = this.authService.canSearch();
|
||||||
this.showShare =
|
this.showShare =
|
||||||
Config.Sharing.enabled &&
|
Config.Sharing.enabled &&
|
||||||
this.authService.isAuthorized(UserRoles.User);
|
this.authService.isAuthorized(UserRoles.User);
|
||||||
this.showRandomPhotoBuilder =
|
this.showRandomPhotoBuilder =
|
||||||
Config.RandomPhoto.enabled &&
|
Config.RandomPhoto.enabled &&
|
||||||
this.authService.isAuthorized(UserRoles.User);
|
this.authService.isAuthorized(UserRoles.User);
|
||||||
this.subscription.content = this.galleryService.sortedFilteredContent
|
this.subscription.content = this.galleryService.sortedFilteredContent
|
||||||
.subscribe((dc: GroupedDirectoryContent) => {
|
.subscribe((dc: GroupedDirectoryContent) => {
|
||||||
this.onContentChange(dc);
|
this.onContentChange(dc);
|
||||||
});
|
});
|
||||||
this.subscription.route = this.route.params.subscribe(this.onRoute);
|
this.subscription.route = this.route.params.subscribe(this.onRoute);
|
||||||
|
|
||||||
if (this.shareService.isSharing()) {
|
if (this.shareService.isSharing()) {
|
||||||
this.$counter = interval(1000);
|
this.$counter = interval(1000);
|
||||||
this.subscription.timer = this.$counter.subscribe((x): void =>
|
this.subscription.timer = this.$counter.subscribe((x): void =>
|
||||||
this.updateTimer(x)
|
this.updateTimer(x)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,18 +151,18 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
params[QueryParams.gallery.sharingKey_params] &&
|
params[QueryParams.gallery.sharingKey_params] &&
|
||||||
params[QueryParams.gallery.sharingKey_params] !== ''
|
params[QueryParams.gallery.sharingKey_params] !== ''
|
||||||
) {
|
) {
|
||||||
const sharing = await this.shareService.currentSharing
|
const sharing = await this.shareService.currentSharing
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
.toPromise();
|
.toPromise();
|
||||||
const qParams: { [key: string]: any } = {};
|
const qParams: { [key: string]: any } = {};
|
||||||
qParams[QueryParams.gallery.sharingKey_query] =
|
qParams[QueryParams.gallery.sharingKey_query] =
|
||||||
this.shareService.getSharingKey();
|
this.shareService.getSharingKey();
|
||||||
this.router
|
this.router
|
||||||
.navigate(['/gallery', sharing.path], {queryParams: qParams})
|
.navigate(['/gallery', sharing.path], {queryParams: qParams})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,8 +186,8 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
for (const mediaGroup of content.mediaGroups) {
|
for (const mediaGroup of content.mediaGroups) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
mediaGroup.media
|
mediaGroup.media
|
||||||
.findIndex((m: PhotoDTO) => !!m.metadata?.positionData?.GPSData?.longitude) !== -1
|
.findIndex((m: PhotoDTO) => !!m.metadata?.positionData?.GPSData?.longitude) !== -1
|
||||||
) {
|
) {
|
||||||
this.isPhotoWithLocation = true;
|
this.isPhotoWithLocation = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {NetworkService} from '../../model/network/network.service';
|
import {NetworkService} from '../../model/network/network.service';
|
||||||
import {CreateSharingDTO, SharingDTO,} from '../../../../common/entities/SharingDTO';
|
import {CreateSharingDTO, SharingDTO, SharingDTOKey,} from '../../../../common/entities/SharingDTO';
|
||||||
import {Router, RoutesRecognized} from '@angular/router';
|
import {Router, RoutesRecognized} from '@angular/router';
|
||||||
import {BehaviorSubject} from 'rxjs';
|
import {BehaviorSubject} from 'rxjs';
|
||||||
import {distinctUntilChanged, filter} from 'rxjs/operators';
|
import {distinctUntilChanged, filter} from 'rxjs/operators';
|
||||||
import {QueryParams} from '../../../../common/QueryParams';
|
import {QueryParams} from '../../../../common/QueryParams';
|
||||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO';
|
||||||
import {Utils} from '../../../../common/Utils';
|
import {Utils} from '../../../../common/Utils';
|
||||||
import {Config} from '../../../../common/config/public/Config';
|
import {Config} from '../../../../common/config/public/Config';
|
||||||
|
|
||||||
@ -21,12 +21,15 @@ export class ShareService {
|
|||||||
inited = false;
|
inited = false;
|
||||||
public ReadyPR: Promise<void>;
|
public ReadyPR: Promise<void>;
|
||||||
public sharingSubject: BehaviorSubject<SharingDTO> = new BehaviorSubject(
|
public sharingSubject: BehaviorSubject<SharingDTO> = new BehaviorSubject(
|
||||||
null
|
null
|
||||||
|
);
|
||||||
|
public sharingIsValid: BehaviorSubject<boolean> = new BehaviorSubject(
|
||||||
|
null
|
||||||
);
|
);
|
||||||
public currentSharing = this.sharingSubject
|
public currentSharing = this.sharingSubject
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.pipe(filter((s) => s !== null))
|
.pipe(filter((s) => s !== null))
|
||||||
.pipe(distinctUntilChanged());
|
.pipe(distinctUntilChanged());
|
||||||
|
|
||||||
private resolve: () => void;
|
private resolve: () => void;
|
||||||
|
|
||||||
@ -41,18 +44,18 @@ export class ShareService {
|
|||||||
this.router.events.subscribe(async (val) => {
|
this.router.events.subscribe(async (val) => {
|
||||||
if (val instanceof RoutesRecognized) {
|
if (val instanceof RoutesRecognized) {
|
||||||
this.param =
|
this.param =
|
||||||
val.state.root.firstChild.params[
|
val.state.root.firstChild.params[
|
||||||
QueryParams.gallery.sharingKey_params
|
QueryParams.gallery.sharingKey_params
|
||||||
] || null;
|
] || null;
|
||||||
this.queryParam =
|
this.queryParam =
|
||||||
val.state.root.firstChild.queryParams[
|
val.state.root.firstChild.queryParams[
|
||||||
QueryParams.gallery.sharingKey_query
|
QueryParams.gallery.sharingKey_query
|
||||||
] || null;
|
] || null;
|
||||||
|
|
||||||
const changed = this.sharingKey !== (this.param || this.queryParam);
|
const changed = this.sharingKey !== (this.param || this.queryParam);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this.sharingKey = this.param || this.queryParam || this.sharingKey;
|
this.sharingKey = this.param || this.queryParam || this.sharingKey;
|
||||||
await this.getSharing();
|
await this.checkSharing();
|
||||||
}
|
}
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve();
|
this.resolve();
|
||||||
@ -69,12 +72,17 @@ export class ShareService {
|
|||||||
|
|
||||||
|
|
||||||
onNewUser = async (user: UserDTO) => {
|
onNewUser = async (user: UserDTO) => {
|
||||||
if (user && !!user.usedSharingKey) {
|
// if this is a sharing user or a logged-in user, get sharing key
|
||||||
|
if (user?.usedSharingKey || user?.role > UserRoles.LimitedGuest) {
|
||||||
if (
|
if (
|
||||||
user.usedSharingKey !== this.sharingKey ||
|
(user?.usedSharingKey &&
|
||||||
this.sharingSubject.value == null
|
user?.usedSharingKey !== this.sharingKey) ||
|
||||||
|
this.sharingSubject.value == null
|
||||||
) {
|
) {
|
||||||
this.sharingKey = user.usedSharingKey;
|
this.sharingKey = user.usedSharingKey || this.getSharingKey();
|
||||||
|
if(!this.sharingKey){ //no key to fetch
|
||||||
|
return
|
||||||
|
}
|
||||||
await this.getSharing();
|
await this.getSharing();
|
||||||
}
|
}
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
@ -93,24 +101,26 @@ export class ShareService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public createSharing(
|
public createSharing(
|
||||||
dir: string,
|
dir: string,
|
||||||
includeSubFolders: boolean,
|
includeSubFolders: boolean,
|
||||||
valid: number
|
password: string,
|
||||||
|
valid: number
|
||||||
): Promise<SharingDTO> {
|
): Promise<SharingDTO> {
|
||||||
return this.networkService.postJson('/share/' + dir, {
|
return this.networkService.postJson('/share/' + dir, {
|
||||||
createSharing: {
|
createSharing: {
|
||||||
includeSubfolders: includeSubFolders,
|
includeSubfolders: includeSubFolders,
|
||||||
valid,
|
valid,
|
||||||
|
...(!!password && {password: password}) // only add password if present
|
||||||
} as CreateSharingDTO,
|
} as CreateSharingDTO,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateSharing(
|
public updateSharing(
|
||||||
dir: string,
|
dir: string,
|
||||||
sharingId: number,
|
sharingId: number,
|
||||||
includeSubFolders: boolean,
|
includeSubFolders: boolean,
|
||||||
password: string,
|
password: string,
|
||||||
valid: number
|
valid: number
|
||||||
): Promise<SharingDTO> {
|
): Promise<SharingDTO> {
|
||||||
return this.networkService.putJson('/share/' + dir, {
|
return this.networkService.putJson('/share/' + dir, {
|
||||||
updateSharing: {
|
updateSharing: {
|
||||||
@ -134,7 +144,7 @@ export class ShareService {
|
|||||||
try {
|
try {
|
||||||
this.sharingSubject.next(null);
|
this.sharingSubject.next(null);
|
||||||
const sharing = await this.networkService.getJson<SharingDTO>(
|
const sharing = await this.networkService.getJson<SharingDTO>(
|
||||||
'/share/' + this.getSharingKey()
|
'/share/' + this.getSharingKey()
|
||||||
);
|
);
|
||||||
this.sharingSubject.next(sharing);
|
this.sharingSubject.next(sharing);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -143,8 +153,21 @@ export class ShareService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async checkSharing(): Promise<void> {
|
||||||
|
try {
|
||||||
|
this.sharingIsValid.next(null);
|
||||||
|
const sharing = await this.networkService.getJson<SharingDTOKey>(
|
||||||
|
'/share/' + this.getSharingKey() + '/key'
|
||||||
|
);
|
||||||
|
this.sharingIsValid.next(sharing.sharingKey === this.getSharingKey());
|
||||||
|
} catch (e) {
|
||||||
|
this.sharingIsValid.next(false);
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async getSharingListForDir(
|
public async getSharingListForDir(
|
||||||
dir: string
|
dir: string
|
||||||
): Promise<SharingDTO[]> {
|
): Promise<SharingDTO[]> {
|
||||||
return this.networkService.getJson('/share/list/' + dir);
|
return this.networkService.getJson('/share/list/' + dir);
|
||||||
}
|
}
|
||||||
|
@ -82,11 +82,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" *ngIf="passwordProtection">
|
<div class="row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label class="control-label" for="share-password">
|
<label class="control-label" for="share-password">
|
||||||
<ng-container i18n>Password</ng-container><!--
|
<ng-container i18n>Password</ng-container>
|
||||||
-->*:
|
<ng-container *ngIf="passwordRequired">*</ng-container>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
@ -98,7 +98,7 @@
|
|||||||
[(ngModel)]="input.password"
|
[(ngModel)]="input.password"
|
||||||
i18n-placeholder
|
i18n-placeholder
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
required>
|
[required]="passwordRequired">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
currentDir = '';
|
currentDir = '';
|
||||||
sharing: SharingDTO = null;
|
sharing: SharingDTO = null;
|
||||||
contentSubscription: Subscription = null;
|
contentSubscription: Subscription = null;
|
||||||
readonly passwordProtection = Config.Sharing.passwordProtected;
|
readonly passwordRequired = Config.Sharing.passwordRequired;
|
||||||
readonly ValidityTypes = ValidityTypes;
|
readonly ValidityTypes = ValidityTypes;
|
||||||
|
|
||||||
modalRef: BsModalRef;
|
modalRef: BsModalRef;
|
||||||
@ -138,11 +138,16 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async get(): Promise<void> {
|
async get(): Promise<void> {
|
||||||
|
if(Config.Sharing.passwordRequired && !this.input.password){
|
||||||
|
this.url = $localize`Set password.`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.urlValid = false;
|
this.urlValid = false;
|
||||||
this.url = $localize`loading..`;
|
this.url = $localize`loading..`;
|
||||||
this.sharing = await this.sharingService.createSharing(
|
this.sharing = await this.sharingService.createSharing(
|
||||||
this.currentDir,
|
this.currentDir,
|
||||||
this.input.includeSubfolders,
|
this.input.includeSubfolders,
|
||||||
|
this.input.password,
|
||||||
this.calcValidity()
|
this.calcValidity()
|
||||||
);
|
);
|
||||||
this.url = this.sharingService.getUrl(this.sharing);
|
this.url = this.sharingService.getUrl(this.sharing);
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row card align-self-center">
|
<div class="row card align-self-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div *ngIf="(shareService.currentSharing | async) == shareService.UnknownSharingKey"
|
<div *ngIf="!(shareService.sharingIsValid | async)"
|
||||||
class="h3 text-center text-danger" i18n>Unknown sharing key.
|
class="h3 text-center text-danger" i18n>Unknown sharing key.
|
||||||
</div>
|
</div>
|
||||||
<form *ngIf="(shareService.currentSharing | async) != shareService.UnknownSharingKey"
|
<form *ngIf="(shareService.sharingIsValid | async)"
|
||||||
name="form" id="form" class="form-horizontal" #LoginForm="ngForm" (submit)="onLogin()">
|
name="form" id="form" class="form-horizontal" #LoginForm="ngForm" (submit)="onLogin()">
|
||||||
<div class="error-message" [hidden]="loginError==false" i18n>Wrong password</div>
|
<div class="error-message" [hidden]="loginError==false" i18n>Wrong password</div>
|
||||||
|
|
||||||
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
<div class="col-sm-12 controls d-grid gap-2">
|
<div class="col-sm-12 controls d-grid gap-2">
|
||||||
<button class="btn btn-primary btn-lg"
|
<button class="btn btn-primary btn-lg"
|
||||||
|
id="button-share-login"
|
||||||
[disabled]="!LoginForm.form.valid || inProgress"
|
[disabled]="!LoginForm.form.valid || inProgress"
|
||||||
type="submit"
|
type="submit"
|
||||||
name="action" i18n>Enter
|
name="action" i18n>Enter
|
||||||
|
@ -75,8 +75,15 @@ describe('PublicRouter', () => {
|
|||||||
.get('/share/' + sharingKey);
|
.get('/share/' + sharingKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should not get default user with passworded share share without password', async () => {
|
it('should not get default user with passworded share without required password', async () => {
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = false;
|
||||||
|
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
||||||
|
const res = await fistLoad(server, sharing.sharingKey);
|
||||||
|
shouldHaveInjectedUser(res, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not get default user with passworded share share with required password', async () => {
|
||||||
|
Config.Sharing.passwordRequired = true;
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
||||||
const res = await fistLoad(server, sharing.sharingKey);
|
const res = await fistLoad(server, sharing.sharingKey);
|
||||||
shouldHaveInjectedUser(res, null);
|
shouldHaveInjectedUser(res, null);
|
||||||
@ -84,25 +91,13 @@ describe('PublicRouter', () => {
|
|||||||
|
|
||||||
|
|
||||||
it('should get default user with no-password share', async () => {
|
it('should get default user with no-password share', async () => {
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = false;
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser);
|
const sharing = await RouteTestingHelper.createSharing(testUser);
|
||||||
const res = await fistLoad(server, sharing.sharingKey);
|
const res = await fistLoad(server, sharing.sharingKey);
|
||||||
shouldHaveInjectedUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
shouldHaveInjectedUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get default user for no-password share when password protection disabled', async () => {
|
|
||||||
Config.Sharing.passwordProtected = false;
|
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser);
|
|
||||||
const res = await fistLoad(server, sharing.sharingKey);
|
|
||||||
shouldHaveInjectedUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get default user for passworded share when password protection disabled', async () => {
|
|
||||||
Config.Sharing.passwordProtected = false;
|
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
|
||||||
const res = await fistLoad(server, sharing.sharingKey);
|
|
||||||
shouldHaveInjectedUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -74,15 +74,32 @@ describe('SharingRouter', () => {
|
|||||||
beforeEach(setUp);
|
beforeEach(setUp);
|
||||||
afterEach(tearDown);
|
afterEach(tearDown);
|
||||||
|
|
||||||
it('should login with passworded share', async () => {
|
it('should login with passworded share when password required', async () => {
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = true;
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
||||||
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
||||||
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should login with passworded share when password not required', async () => {
|
||||||
|
Config.Sharing.passwordRequired = false;
|
||||||
|
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
||||||
|
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
||||||
|
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should login without passworded share when password not required', async () => {
|
||||||
|
Config.Sharing.passwordRequired = false;
|
||||||
|
const sharing = await RouteTestingHelper.createSharing(testUser );
|
||||||
|
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
||||||
|
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should not login with passworded share without password', async () => {
|
it('should not login with passworded share without password', async () => {
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = true;
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
||||||
const result = await shareLogin(server, sharing.sharingKey);
|
const result = await shareLogin(server, sharing.sharingKey);
|
||||||
|
|
||||||
@ -92,22 +109,22 @@ describe('SharingRouter', () => {
|
|||||||
should.equal(result.body.error.code, ErrorCodes.CREDENTIAL_NOT_FOUND);
|
should.equal(result.body.error.code, ErrorCodes.CREDENTIAL_NOT_FOUND);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not login with passworded share but password protection disabled', async () => {
|
|
||||||
Config.Sharing.passwordProtected = false;
|
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser, 'secret_pass');
|
|
||||||
const res = await shareLogin(server, sharing.sharingKey);
|
|
||||||
|
|
||||||
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
it('should not login to share without password when password required', async () => {
|
||||||
});
|
Config.Sharing.passwordRequired = false;
|
||||||
|
|
||||||
it('should login with no-password share', async () => {
|
|
||||||
Config.Sharing.passwordProtected = true;
|
|
||||||
const sharing = await RouteTestingHelper.createSharing(testUser);
|
const sharing = await RouteTestingHelper.createSharing(testUser);
|
||||||
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
Config.Sharing.passwordRequired = true;
|
||||||
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
const result = await shareLogin(server, sharing.sharingKey);
|
||||||
|
|
||||||
|
result.should.have.status(401);
|
||||||
|
result.body.should.be.a('object');
|
||||||
|
result.body.error.should.be.a('object');
|
||||||
|
should.equal(result.body.error.code, ErrorCodes.CREDENTIAL_NOT_FOUND);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,9 +125,9 @@ describe('UserRouter', () => {
|
|||||||
it('it should authenticate as user with sharing key', async () => {
|
it('it should authenticate as user with sharing key', async () => {
|
||||||
Config.Users.authenticationRequired = true;
|
Config.Users.authenticationRequired = true;
|
||||||
Config.Sharing.enabled = true;
|
Config.Sharing.enabled = true;
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = true;
|
||||||
|
|
||||||
const sharingKey = (await RouteTestingHelper.createSharing(testUser)).sharingKey;
|
const sharingKey = (await RouteTestingHelper.createSharing(testUser, 'pass')).sharingKey;
|
||||||
|
|
||||||
|
|
||||||
const loginRes = await login(server);
|
const loginRes = await login(server);
|
||||||
@ -146,7 +146,7 @@ describe('UserRouter', () => {
|
|||||||
it('it should authenticate with sharing key', async () => {
|
it('it should authenticate with sharing key', async () => {
|
||||||
Config.Users.authenticationRequired = true;
|
Config.Users.authenticationRequired = true;
|
||||||
Config.Sharing.enabled = true;
|
Config.Sharing.enabled = true;
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = false;
|
||||||
const sharing = (await RouteTestingHelper.createSharing(testUser));
|
const sharing = (await RouteTestingHelper.createSharing(testUser));
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ describe('UserRouter', () => {
|
|||||||
it('it should not authenticate with sharing key without password', async () => {
|
it('it should not authenticate with sharing key without password', async () => {
|
||||||
Config.Users.authenticationRequired = true;
|
Config.Users.authenticationRequired = true;
|
||||||
Config.Sharing.enabled = true;
|
Config.Sharing.enabled = true;
|
||||||
Config.Sharing.passwordProtected = true;
|
Config.Sharing.passwordRequired = true;
|
||||||
const sharing = (await RouteTestingHelper.createSharing(testUser, 'pass_secret'));
|
const sharing = (await RouteTestingHelper.createSharing(testUser, 'pass_secret'));
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user