1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-01-08 04:03:48 +02:00

Moving /api to /pgapi and making it configurable #214, #519

This commit is contained in:
Patrik J. Braun 2022-12-10 00:04:08 +01:00
parent f8606df759
commit be7937293b
23 changed files with 205 additions and 169 deletions

View File

@ -1,10 +1,11 @@
import { AuthenticationMWs } from '../middlewares/user/AuthenticationMWs';
import { Express } from 'express';
import { RenderingMWs } from '../middlewares/RenderingMWs';
import { UserRoles } from '../../common/entities/UserDTO';
import { VersionMWs } from '../middlewares/VersionMWs';
import { AlbumMWs } from '../middlewares/AlbumMWs';
import { ServerTimingMWs } from '../middlewares/ServerTimingMWs';
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
import {Express} from 'express';
import {RenderingMWs} from '../middlewares/RenderingMWs';
import {UserRoles} from '../../common/entities/UserDTO';
import {VersionMWs} from '../middlewares/VersionMWs';
import {AlbumMWs} from '../middlewares/AlbumMWs';
import {ServerTimingMWs} from '../middlewares/ServerTimingMWs';
import {Config} from '../../common/config/private/Config';
export class AlbumRouter {
public static route(app: Express): void {
@ -15,7 +16,7 @@ export class AlbumRouter {
private static addListAlbums(app: Express): void {
app.get(
['/api/albums'],
[Config.Client.apiPath + '/albums'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.User),
@ -30,7 +31,7 @@ export class AlbumRouter {
private static addDeleteAlbum(app: Express): void {
app.delete(
['/api/albums/:id'],
[Config.Client.apiPath + '/albums/:id'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
@ -45,7 +46,7 @@ export class AlbumRouter {
private static addAddSavedSearch(app: Express): void {
app.put(
['/api/albums/saved-searches'],
[Config.Client.apiPath + '/albums/saved-searches'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),

View File

@ -2,6 +2,7 @@ import { RenderingMWs } from '../middlewares/RenderingMWs';
import { ErrorCodes, ErrorDTO } from '../../common/entities/Error';
import { Logger } from '../Logger';
import { Express, NextFunction, Request, Response } from 'express';
import {Config} from '../../common/config/private/Config';
export class ErrorRouter {
public static route(app: Express): void {
@ -10,7 +11,7 @@ export class ErrorRouter {
}
private static addApiErrorHandler(app: Express): void {
app.use('/api/*', RenderingMWs.renderError);
app.use(Config.Client.apiPath + '/*', RenderingMWs.renderError);
}
private static addGenericHandler(app: Express): void {

View File

@ -1,15 +1,16 @@
import { AuthenticationMWs } from '../middlewares/user/AuthenticationMWs';
import { Express } from 'express';
import { GalleryMWs } from '../middlewares/GalleryMWs';
import { RenderingMWs } from '../middlewares/RenderingMWs';
import { ThumbnailGeneratorMWs } from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
import { UserRoles } from '../../common/entities/UserDTO';
import { ThumbnailSourceType } from '../model/threading/PhotoWorker';
import { VersionMWs } from '../middlewares/VersionMWs';
import { SupportedFormats } from '../../common/SupportedFormats';
import { PhotoConverterMWs } from '../middlewares/thumbnail/PhotoConverterMWs';
import { ServerTimingMWs } from '../middlewares/ServerTimingMWs';
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
import {Express} from 'express';
import {GalleryMWs} from '../middlewares/GalleryMWs';
import {RenderingMWs} from '../middlewares/RenderingMWs';
import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
import {UserRoles} from '../../common/entities/UserDTO';
import {ThumbnailSourceType} from '../model/threading/PhotoWorker';
import {VersionMWs} from '../middlewares/VersionMWs';
import {SupportedFormats} from '../../common/SupportedFormats';
import {PhotoConverterMWs} from '../middlewares/thumbnail/PhotoConverterMWs';
import {ServerTimingMWs} from '../middlewares/ServerTimingMWs';
import {MetaFileMWs} from '../middlewares/MetaFileMWs';
import {Config} from '../../common/config/private/Config';
export class GalleryRouter {
public static route(app: Express): void {
@ -33,7 +34,7 @@ export class GalleryRouter {
protected static addDirectoryList(app: Express): void {
app.get(
['/api/gallery/content/:directory(*)', '/api/gallery/', '/api/gallery//'],
[Config.Client.apiPath + '/gallery/content/:directory(*)', Config.Client.apiPath + '/gallery/', Config.Client.apiPath + '/gallery//'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('directory'),
@ -51,7 +52,7 @@ export class GalleryRouter {
protected static addDirectoryZip(app: Express): void {
app.get(
['/api/gallery/zip/:directory(*)'],
[Config.Client.apiPath + '/gallery/zip/:directory(*)'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('directory'),
@ -66,9 +67,9 @@ export class GalleryRouter {
protected static addGetImage(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))',
],
// common part
AuthenticationMWs.authenticate,
@ -85,9 +86,9 @@ export class GalleryRouter {
protected static addGetBestFitImage(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/bestFit',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/bestFit',
],
// common part
AuthenticationMWs.authenticate,
@ -105,9 +106,9 @@ export class GalleryRouter {
protected static addGetVideo(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))',
],
// common part
AuthenticationMWs.authenticate,
@ -124,9 +125,9 @@ export class GalleryRouter {
protected static addGetBestFitVideo(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/bestFit',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/bestFit',
],
// common part
AuthenticationMWs.authenticate,
@ -144,9 +145,9 @@ export class GalleryRouter {
protected static addGetMetaFile(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.MetaFiles.join('|') +
'))',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.MetaFiles.join('|') +
'))',
],
// common part
AuthenticationMWs.authenticate,
@ -163,7 +164,7 @@ export class GalleryRouter {
protected static addGetBestFitMetaFile(app: Express): void {
app.get(
[
'/api/gallery/content/:mediaPath(*.(' +
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.MetaFiles.join('|') +
'))/bestFit',
],
@ -182,7 +183,7 @@ export class GalleryRouter {
protected static addRandom(app: Express): void {
app.get(
['/api/gallery/random/:searchQueryDTO'],
[Config.Client.apiPath + '/gallery/random/:searchQueryDTO'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Guest),
@ -198,9 +199,9 @@ export class GalleryRouter {
protected static addGetPhotoThumbnail(app: Express): void {
app.get(
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/thumbnail/:size?',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/thumbnail/:size?',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('mediaPath'),
@ -216,9 +217,9 @@ export class GalleryRouter {
protected static addGetVideoThumbnail(app: Express): void {
app.get(
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/thumbnail/:size?',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/thumbnail/:size?',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('mediaPath'),
@ -234,9 +235,9 @@ export class GalleryRouter {
protected static addGetVideoIcon(app: Express): void {
app.get(
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/icon',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Videos.join('|') +
'))/icon',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('mediaPath'),
@ -252,9 +253,9 @@ export class GalleryRouter {
protected static addGetImageIcon(app: Express): void {
app.get(
'/api/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/icon',
Config.Client.apiPath + '/gallery/content/:mediaPath(*.(' +
SupportedFormats.Photos.join('|') +
'))/icon',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.normalizePathParam('mediaPath'),
@ -270,7 +271,7 @@ export class GalleryRouter {
protected static addSearch(app: Express): void {
app.get(
'/api/search/:searchQueryDTO(*)',
Config.Client.apiPath + '/search/:searchQueryDTO(*)',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Guest),
@ -287,7 +288,7 @@ export class GalleryRouter {
protected static addAutoComplete(app: Express): void {
app.get(
'/api/autocomplete/:text(*)',
Config.Client.apiPath + '/autocomplete/:text(*)',
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Guest),

View File

@ -1,5 +1,6 @@
import { Express, NextFunction, Request, Response } from 'express';
import { logFN, Logger } from '../Logger';
import {Config} from '../../common/config/private/Config';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
@ -41,7 +42,7 @@ export class LoggerRouter {
return next();
});
app.get('/api*', (req: Request, res: Response, next: NextFunction): any => {
app.get(Config.Client.apiPath + '*', (req: Request, res: Response, next: NextFunction): any => {
LoggerRouter.log(Logger.verbose, req, res);
return next();
});

View File

@ -5,6 +5,7 @@ import { NotificationMWs } from '../middlewares/NotificationMWs';
import { Express } from 'express';
import { VersionMWs } from '../middlewares/VersionMWs';
import { ServerTimingMWs } from '../middlewares/ServerTimingMWs';
import {Config} from '../../common/config/private/Config';
export class NotificationRouter {
public static route(app: Express): void {
@ -13,7 +14,7 @@ export class NotificationRouter {
private static addGetNotifications(app: Express): void {
app.get(
'/api/notifications',
Config.Client.apiPath + '/notifications',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Guest),
VersionMWs.injectGalleryVersion,

View File

@ -17,7 +17,7 @@ export class PersonRouter {
protected static updatePerson(app: Express): void {
app.post(
['/api/person/:name'],
[Config.Client.apiPath + '/person/:name'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(Config.Client.Faces.writeAccessMinRole),
@ -32,7 +32,7 @@ export class PersonRouter {
protected static addGetPersons(app: Express): void {
app.get(
['/api/person'],
[Config.Client.apiPath + '/person'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(Config.Client.Faces.readAccessMinRole),
@ -50,7 +50,7 @@ export class PersonRouter {
protected static getPersonThumbnail(app: Express): void {
app.get(
['/api/person/:name/thumbnail'],
[Config.Client.apiPath + '/person/:name/thumbnail'],
// common part
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.User),

View File

@ -5,6 +5,7 @@ import { SharingMWs } from '../middlewares/SharingMWs';
import * as express from 'express';
import { QueryParams } from '../../common/QueryParams';
import { ServerTimingMWs } from '../middlewares/ServerTimingMWs';
import {Config} from '../../common/config/private/Config';
export class SharingRouter {
public static route(app: express.Express): void {
@ -18,7 +19,7 @@ export class SharingRouter {
private static addShareLogin(app: express.Express): void {
app.post(
'/api/share/login',
Config.Client.apiPath + '/share/login',
AuthenticationMWs.inverseAuthenticate,
AuthenticationMWs.shareLogin,
ServerTimingMWs.addServerTiming,
@ -28,7 +29,7 @@ export class SharingRouter {
private static addGetSharing(app: express.Express): void {
app.get(
'/api/share/:' + QueryParams.gallery.sharingKey_params,
Config.Client.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params,
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.LimitedGuest),
SharingMWs.getSharing,
@ -39,7 +40,7 @@ export class SharingRouter {
private static addCreateSharing(app: express.Express): void {
app.post(
['/api/share/:directory(*)', '/api/share/', '/api/share//'],
[Config.Client.apiPath + '/share/:directory(*)', Config.Client.apiPath + '/share/', Config.Client.apiPath + '/share//'],
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.User),
SharingMWs.createSharing,
@ -50,7 +51,7 @@ export class SharingRouter {
private static addUpdateSharing(app: express.Express): void {
app.put(
['/api/share/:directory(*)', '/api/share/', '/api/share//'],
[Config.Client.apiPath + '/share/:directory(*)', Config.Client.apiPath + '/share/', Config.Client.apiPath + '/share//'],
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.User),
SharingMWs.updateSharing,
@ -61,7 +62,7 @@ export class SharingRouter {
private static addDeleteSharing(app: express.Express): void {
app.delete(
['/api/share/:sharingKey'],
[Config.Client.apiPath + '/share/:sharingKey'],
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SharingMWs.deleteSharing,
@ -72,7 +73,7 @@ export class SharingRouter {
private static addListSharing(app: express.Express): void {
app.get(
['/api/share/list'],
[Config.Client.apiPath + '/share/list'],
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.User),
SharingMWs.listSharing,

View File

@ -5,6 +5,7 @@ import { AuthenticationMWs } from '../middlewares/user/AuthenticationMWs';
import { UserRequestConstrainsMWs } from '../middlewares/user/UserRequestConstrainsMWs';
import { RenderingMWs } from '../middlewares/RenderingMWs';
import { ServerTimingMWs } from '../middlewares/ServerTimingMWs';
import { Config } from '../../common/config/private/Config';
export class UserRouter {
public static route(app: Express): void {
@ -20,7 +21,7 @@ export class UserRouter {
private static addLogin(app: Express): void {
app.post(
'/api/user/login',
Config.Client.apiPath + '/user/login',
AuthenticationMWs.inverseAuthenticate,
AuthenticationMWs.login,
ServerTimingMWs.addServerTiming,
@ -30,7 +31,7 @@ export class UserRouter {
private static addLogout(app: Express): void {
app.post(
'/api/user/logout',
Config.Client.apiPath + '/user/logout',
AuthenticationMWs.logout,
ServerTimingMWs.addServerTiming,
RenderingMWs.renderOK
@ -39,7 +40,7 @@ export class UserRouter {
private static addGetSessionUser(app: Express): void {
app.get(
'/api/user/me',
Config.Client.apiPath + '/user/me',
AuthenticationMWs.authenticate,
ServerTimingMWs.addServerTiming,
RenderingMWs.renderSessionUser
@ -48,7 +49,7 @@ export class UserRouter {
private static addCreateUser(app: Express): void {
app.put(
'/api/user',
Config.Client.apiPath + '/user',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
UserMWs.createUser,
@ -59,7 +60,7 @@ export class UserRouter {
private static addDeleteUser(app: Express): void {
app.delete(
'/api/user/:id',
Config.Client.apiPath + '/user/:id',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
UserRequestConstrainsMWs.notSelfRequest,
@ -71,7 +72,7 @@ export class UserRouter {
private static addListUsers(app: Express): void {
app.get(
'/api/user/list',
Config.Client.apiPath + '/user/list',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
UserMWs.listUsers,
@ -82,7 +83,7 @@ export class UserRouter {
private static addChangeRole(app: Express): void {
app.post(
'/api/user/:id/role',
Config.Client.apiPath + '/user/:id/role',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
UserRequestConstrainsMWs.notSelfRequestOr2Admins,

View File

@ -3,6 +3,7 @@ import { UserRoles } from '../../../common/entities/UserDTO';
import { RenderingMWs } from '../../middlewares/RenderingMWs';
import { AdminMWs } from '../../middlewares/admin/AdminMWs';
import { Express } from 'express';
import { Config } from '../../../common/config/private/Config';
export class AdminRouter {
public static route(app: Express): void {
@ -13,7 +14,7 @@ export class AdminRouter {
private static addGetStatistic(app: Express): void {
app.get(
'/api/admin/statistic',
Config.Client.apiPath + '/admin/statistic',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.loadStatistic,
@ -23,7 +24,7 @@ export class AdminRouter {
private static addGetDuplicates(app: Express): void {
app.get(
'/api/admin/duplicates',
Config.Client.apiPath + '/admin/duplicates',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.getDuplicates,
@ -33,28 +34,28 @@ export class AdminRouter {
private static addJobs(app: Express): void {
app.get(
'/api/admin/jobs/available',
Config.Client.apiPath + '/admin/jobs/available',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.getAvailableJobs,
RenderingMWs.renderResult
);
app.get(
'/api/admin/jobs/scheduled/progress',
Config.Client.apiPath + '/admin/jobs/scheduled/progress',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.getJobProgresses,
RenderingMWs.renderResult
);
app.post(
'/api/admin/jobs/scheduled/:id/start',
Config.Client.apiPath + '/admin/jobs/scheduled/:id/start',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.startJob,
RenderingMWs.renderResult
);
app.post(
'/api/admin/jobs/scheduled/:id/stop',
Config.Client.apiPath + '/admin/jobs/scheduled/:id/stop',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.stopJob,

View File

@ -3,6 +3,7 @@ import { UserRoles } from '../../../common/entities/UserDTO';
import { RenderingMWs } from '../../middlewares/RenderingMWs';
import { Express } from 'express';
import { SettingsMWs } from '../../middlewares/admin/SettingsMWs';
import { Config } from '../../../common/config/private/Config';
export class SettingsRouter {
public static route(app: Express): void {
@ -11,14 +12,14 @@ export class SettingsRouter {
private static addSettings(app: Express): void {
app.get(
'/api/settings',
Config.Client.apiPath + '/settings',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
RenderingMWs.renderConfig
);
app.put(
'/api/settings/database',
Config.Client.apiPath + '/settings/database',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateDatabaseSettings,
@ -26,28 +27,28 @@ export class SettingsRouter {
);
app.put(
'/api/settings/map',
Config.Client.apiPath + '/settings/map',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateMapSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/video',
Config.Client.apiPath + '/settings/video',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateVideoSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/photo',
Config.Client.apiPath + '/settings/photo',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updatePhotoSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/metafile',
Config.Client.apiPath + '/settings/metafile',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateMetaFileSettings,
@ -55,84 +56,84 @@ export class SettingsRouter {
);
app.put(
'/api/settings/authentication',
Config.Client.apiPath + '/settings/authentication',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateAuthenticationSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/thumbnail',
Config.Client.apiPath + '/settings/thumbnail',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateThumbnailSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/search',
Config.Client.apiPath + '/settings/search',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateSearchSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/preview',
Config.Client.apiPath + '/settings/preview',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updatePreviewSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/faces',
Config.Client.apiPath + '/settings/faces',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateFacesSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/albums',
Config.Client.apiPath + '/settings/albums',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateAlbumsSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/share',
Config.Client.apiPath + '/settings/share',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateShareSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/randomPhoto',
Config.Client.apiPath + '/settings/randomPhoto',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateRandomPhotoSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/basic',
Config.Client.apiPath + '/settings/basic',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateBasicSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/other',
Config.Client.apiPath + '/settings/other',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateOtherSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/indexing',
Config.Client.apiPath + '/settings/indexing',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateIndexingSettings,
RenderingMWs.renderOK
);
app.put(
'/api/settings/jobs',
Config.Client.apiPath + '/settings/jobs',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updateJobSettings,

View File

@ -93,7 +93,7 @@ export class Server {
csuf.unless((req: Request) => {
return (
Config.Client.authenticationRequired === false ||
['/api/user/login', '/api/user/logout', '/api/share/login'].indexOf(
[Config.Client.apiPath + '/user/login', Config.Client.apiPath + '/user/logout', Config.Client.apiPath + '/share/login'].indexOf(
req.originalUrl
) !== -1 ||
(Config.Client.Sharing.enabled === true &&
@ -104,11 +104,11 @@ export class Server {
// enable token generation but do not check it
this.app.post(
['/api/user/login', '/api/share/login'],
[Config.Client.apiPath + '/user/login', Config.Client.apiPath + '/share/login'],
_csrf({ignoreMethods: ['POST']})
);
this.app.get(
['/api/user/me', '/api/share/:' + QueryParams.gallery.sharingKey_params],
[Config.Client.apiPath + '/user/me', Config.Client.apiPath + '/share/:' + QueryParams.gallery.sharingKey_params],
_csrf({ignoreMethods: ['GET']})
);

View File

@ -144,16 +144,19 @@ export class ClientOtherConfig {
enableCache: boolean = true;
@ConfigProperty()
enableOnScrollRendering: boolean = true;
@ConfigProperty({type: SortingMethods,description:'Default sorting method for directory results'})
@ConfigProperty({type: SortingMethods, description: 'Default sorting method for directory results'})
defaultPhotoSortingMethod: SortingMethods = SortingMethods.ascDate;
@ConfigProperty({type: SortingMethods,description:'Default sorting method for search results'})
@ConfigProperty({type: SortingMethods, description: 'Default sorting method for search results'})
defaultSearchSortingMethod: SortingMethods = SortingMethods.descDate;
@ConfigProperty({
description:
'If enabled directories will be sorted by date, like photos, otherwise by name. Directory date is the last modification time of that directory not the creation date of the oldest photo',
})
enableDirectorySortingByDate: boolean = false;
enableDirectorySortingByDate: boolean = false;
@ConfigProperty()
enableOnScrollThumbnailPrioritising: boolean = true;
@ConfigProperty()
@ -259,34 +262,52 @@ export class ClientFacesConfig {
@SubConfigClass()
export class ClientConfig {
@ConfigProperty()
applicationTitle: string = 'PiGallery 2';
@ConfigProperty()
publicUrl: string = '';
@ConfigProperty()
urlBase: string = '';
@ConfigProperty({description: 'PiGallery api path.'})
apiPath: string = '/pgapi';
@ConfigProperty()
Search: ClientSearchConfig = new ClientSearchConfig();
@ConfigProperty()
Sharing: ClientSharingConfig = new ClientSharingConfig();
@ConfigProperty()
Album: ClientAlbumConfig = new ClientAlbumConfig();
@ConfigProperty()
Map: ClientMapConfig = new ClientMapConfig();
@ConfigProperty()
RandomPhoto: ClientRandomPhotoConfig = new ClientRandomPhotoConfig();
@ConfigProperty()
Other: ClientOtherConfig = new ClientOtherConfig();
@ConfigProperty()
authenticationRequired: boolean = true;
@ConfigProperty({type: UserRoles})
unAuthenticatedUserRole: UserRoles = UserRoles.Admin;
@ConfigProperty({arrayType: 'string', volatile: true})
languages: string[] | undefined;
@ConfigProperty()
Media: ClientMediaConfig = new ClientMediaConfig();
@ConfigProperty()
MetaFile: ClientMetaFileConfig = new ClientMetaFileConfig();
@ConfigProperty()
Faces: ClientFacesConfig = new ClientFacesConfig();
}

View File

@ -1,16 +1,17 @@
import { getTestBed, inject, TestBed } from '@angular/core/testing';
import {getTestBed, inject, TestBed} from '@angular/core/testing';
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing';
import { NetworkService } from './network.service';
import { Message } from '../../../../common/entities/Message';
import { LoadingBarService } from '@ngx-loading-bar/core';
import { VersionService } from '../version.service';
import {NetworkService} from './network.service';
import {Message} from '../../../../common/entities/Message';
import {LoadingBarService} from '@ngx-loading-bar/core';
import {VersionService} from '../version.service';
import {Config} from '../../../../common/config/public/Config';
describe('NetworkService Success tests', () => {
const testUrl = '/test/url';
const testData = { data: 'testData' };
const testData = {data: 'testData'};
const testResponse = 'testResponse';
const testResponseMessage = new Message(null, testResponse);
let injector;
@ -42,7 +43,7 @@ describe('NetworkService Success tests', () => {
expect(err).toBeUndefined();
});
const mockReq = httpMock.expectOne({ method: 'GET' });
const mockReq = httpMock.expectOne({method: 'GET'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.flush(testResponseMessage);
@ -62,7 +63,7 @@ describe('NetworkService Success tests', () => {
expect(err).toBeUndefined();
});
let mockReq = httpMock.expectOne('/api' + testUrl);
let mockReq = httpMock.expectOne(Config.Client.apiPath + testUrl);
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.flush(testResponseMessage);
@ -78,7 +79,7 @@ describe('NetworkService Success tests', () => {
expect(err).toBeUndefined();
});
mockReq = httpMock.expectOne('/api' + testUrl);
mockReq = httpMock.expectOne(Config.Client.apiPath + testUrl);
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
expect(mockReq.request.body).toEqual({});
@ -93,7 +94,7 @@ describe('NetworkService Success tests', () => {
expect(res).toBe(testResponse);
});
const mockReq = httpMock.expectOne({ method: 'DELETE' });
const mockReq = httpMock.expectOne({method: 'DELETE'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.flush(testResponseMessage);
@ -128,7 +129,7 @@ describe('NetworkService Success tests', () => {
describe('NetworkService Fail tests', () => {
const testUrl = '/test/url';
const testData = { data: 'testData' };
const testData = {data: 'testData'};
const testError = 'testError';
let injector;
let httpMock: HttpTestingController;
@ -156,14 +157,14 @@ describe('NetworkService Fail tests', () => {
})
.catch((err) => {
expect(err).toBe(
'Http failure response for /api/test/url: 0 ' + testError
`Http failure response for ${Config.Client.apiPath}/test/url: 0 ` + testError
);
});
const mockReq = httpMock.expectOne({ method: 'GET' });
const mockReq = httpMock.expectOne({method: 'GET'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.error(null, { statusText: testError });
mockReq.error(null, {statusText: testError});
}
));
@ -177,15 +178,15 @@ describe('NetworkService Fail tests', () => {
})
.catch((err) => {
expect(err).toBe(
'Http failure response for /api/test/url: 0 ' + testError
`Http failure response for ${Config.Client.apiPath}/test/url: 0 ` + testError
);
});
const mockReq = httpMock.expectOne({ method: 'POST' });
const mockReq = httpMock.expectOne({method: 'POST'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
expect(mockReq.request.body).toEqual(testData);
mockReq.error(null, { statusText: testError });
mockReq.error(null, {statusText: testError});
}
));
@ -199,15 +200,15 @@ describe('NetworkService Fail tests', () => {
})
.catch((err) => {
expect(err).toBe(
'Http failure response for /api/test/url: 0 ' + testError
`Http failure response for ${Config.Client.apiPath}/test/url: 0 ` + testError
);
});
const mockReq = httpMock.expectOne({ method: 'PUT' });
const mockReq = httpMock.expectOne({method: 'PUT'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
expect(mockReq.request.body).toEqual(testData);
mockReq.error(null, { statusText: testError });
mockReq.error(null, {statusText: testError});
}
));
@ -221,14 +222,14 @@ describe('NetworkService Fail tests', () => {
})
.catch((err) => {
expect(err).toBe(
'Http failure response for /api/test/url: 0 ' + testError
`Http failure response for ${Config.Client.apiPath}/test/url: 0 ` + testError
);
});
const mockReq = httpMock.expectOne({ method: 'DELETE' });
const mockReq = httpMock.expectOne({method: 'DELETE'});
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.error(null, { statusText: testError });
mockReq.error(null, {statusText: testError});
}
));
});

View File

@ -10,7 +10,7 @@ import { VersionService } from '../version.service';
@Injectable()
export class NetworkService {
readonly apiBaseUrl = Utils.concatUrls(Config.Client.urlBase, '/api');
readonly apiBaseUrl = Utils.concatUrls(Config.Client.urlBase, Config.Client.apiPath);
private globalErrorHandlers: Array<(error: ErrorDTO) => boolean> = [];
constructor(

View File

@ -12,7 +12,7 @@ export class Person implements PersonDTO {
public static getThumbnailUrl(that: PersonDTO): string {
return Utils.concatUrls(
Config.Client.urlBase,
'/api/person/',
Config.Client.apiPath + '/person/',
encodeURIComponent(that.name),
'/thumbnail'
);

View File

@ -1,7 +1,7 @@
import { Utils } from '../../../../common/Utils';
import { MediaIcon } from './MediaIcon';
import { Config } from '../../../../common/config/public/Config';
import { MediaDTO, MediaDTOUtils } from '../../../../common/entities/MediaDTO';
import {Utils} from '../../../../common/Utils';
import {MediaIcon} from './MediaIcon';
import {Config} from '../../../../common/config/public/Config';
import {MediaDTO, MediaDTOUtils} from '../../../../common/entities/MediaDTO';
export class Media extends MediaIcon {
static readonly sortedThumbnailSizes =
@ -41,7 +41,7 @@ export class Media extends MediaIcon {
// eslint-disable-next-line no-bitwise
if (
(this.media.missingThumbnails & MediaIcon.ThumbnailMap[thSize]) ===
0 &&
0 &&
thSize < size
) {
this.replacementSizeCache = thSize;
@ -70,7 +70,8 @@ export class Media extends MediaIcon {
const size = this.getReplacementThumbnailSize();
return Utils.concatUrls(
Config.Client.urlBase,
'/api/gallery/content/',
Config.Client.apiPath,
'/gallery/content/',
this.getRelativePath(),
'thumbnail',
size.toString()
@ -85,7 +86,8 @@ export class Media extends MediaIcon {
const size = this.getThumbnailSize();
return Utils.concatUrls(
Config.Client.urlBase,
'/api/gallery/content/',
Config.Client.apiPath,
'/gallery/content/',
this.getRelativePath(),
'thumbnail',
size.toString()

View File

@ -49,7 +49,8 @@ export class MediaIcon {
getIconPath(): string {
return Utils.concatUrls(
Config.Client.urlBase,
'/api/gallery/content/',
Config.Client.apiPath,
'/gallery/content/',
this.getRelativePath(),
'icon'
);
@ -58,7 +59,8 @@ export class MediaIcon {
getMediaPath(): string {
return Utils.concatUrls(
Config.Client.urlBase,
'/api/gallery/content/',
Config.Client.apiPath,
'/gallery/content/',
this.getRelativePath()
);
}

View File

@ -1,24 +1,24 @@
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { UserDTOUtils } from '../../../../../common/entities/UserDTO';
import { AuthenticationService } from '../../../model/network/authentication.service';
import { QueryService } from '../../../model/query.service';
import {Component} from '@angular/core';
import {RouterLink} from '@angular/router';
import {UserDTOUtils} from '../../../../../common/entities/UserDTO';
import {AuthenticationService} from '../../../model/network/authentication.service';
import {QueryService} from '../../../model/query.service';
import {
ContentService,
ContentWrapperWithError,
DirectoryContent,
} from '../content.service';
import { Utils } from '../../../../../common/Utils';
import { SortingMethods } from '../../../../../common/entities/SortingMethods';
import { Config } from '../../../../../common/config/public/Config';
import {Utils} from '../../../../../common/Utils';
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
import {Config} from '../../../../../common/config/public/Config';
import {
SearchQueryTypes,
TextSearch,
TextSearchQueryMatchTypes,
} from '../../../../../common/entities/SearchQueryDTO';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { GallerySortingService } from './sorting.service';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {GallerySortingService} from './sorting.service';
@Component({
selector: 'app-gallery-navbar',
@ -60,8 +60,8 @@ export class GalleryNavigatorComponent {
return c.directory
? c.directory.mediaCount
: c.searchResult
? c.searchResult.media.length
: 0;
? c.searchResult.media.length
: 0;
}
get Routes(): NavigatorPath[] {
@ -88,7 +88,7 @@ export class GalleryNavigatorComponent {
// create root link
if (dirs.length === 0) {
arr.push({ name: this.RootFolderName, route: null });
arr.push({name: this.RootFolderName, route: null});
} else {
arr.push({
name: this.RootFolderName,
@ -102,7 +102,7 @@ export class GalleryNavigatorComponent {
dirs.forEach((name, index) => {
const route = dirs.slice(0, dirs.indexOf(name) + 1).join('/');
if (dirs.length - 1 === index) {
arr.push({ name, route: null });
arr.push({name, route: null});
} else {
arr.push({
name,
@ -137,7 +137,8 @@ export class GalleryNavigatorComponent {
});
return Utils.concatUrls(
Config.Client.urlBase,
'/api/gallery/zip/',
Config.Client.apiPath,
'/gallery/zip/',
c.directory.path,
c.directory.name,
'?' + queryParams

View File

@ -60,7 +60,7 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
onQueryChange(): void {
this.url = NetworkService.buildUrl(
Config.Client.publicUrl + '/api/gallery/random/' + this.HTMLSearchQuery
Config.Client.publicUrl + Config.Client.apiPath + '/gallery/random/' + this.HTMLSearchQuery
);
}

View File

@ -55,7 +55,7 @@ describe('GalleryRouter', (sqlHelper: DBTestHelper) => {
it('should load gallery', async () => {
const result = await (chai.request(server.App) as SuperAgentStatic)
.get('/api/gallery/content/');
.get(Config.Client.apiPath + '/gallery/content/');
(result.should as any).have.status(200);
expect(result.body.error).to.be.equal(null);
@ -66,10 +66,10 @@ describe('GalleryRouter', (sqlHelper: DBTestHelper) => {
it('should load gallery twice (to force loading form db)', async () => {
Config.Server.Indexing.reIndexingSensitivity = ReIndexingSensitivity.low;
const _ = await (chai.request(server.App) as SuperAgentStatic)
.get('/api/gallery/content/orientation');
.get(Config.Client.apiPath + '/gallery/content/orientation');
const result = await (chai.request(server.App) as SuperAgentStatic)
.get('/api/gallery/content/orientation');
.get(Config.Client.apiPath + '/gallery/content/orientation');
(result.should as any).have.status(200);
expect(result.body.error).to.be.equal(null);
@ -87,7 +87,7 @@ describe('GalleryRouter', (sqlHelper: DBTestHelper) => {
it('should get video without transcoding', async () => {
const result = await (chai.request(server.App) as SuperAgentStatic)
.get('/api/gallery/content/video.mp4/bestFit');
.get(Config.Client.apiPath + '/gallery/content/video.mp4/bestFit');
(result.should as any).have.status(200);
expect(result.body).to.be.instanceof(Buffer);

View File

@ -64,14 +64,14 @@ describe('SharingRouter', () => {
const shareLogin = async (srv: Server, sharingKey: string, password?: string): Promise<any> => {
return (chai.request(srv.App) as SuperAgentStatic)
.post('/api/share/login?' + QueryParams.gallery.sharingKey_query + '=' + sharingKey)
.post(Config.Client.apiPath + '/share/login?' + QueryParams.gallery.sharingKey_query + '=' + sharingKey)
.send({password});
};
const login = async (srv: Server): Promise<any> => {
const result = await (chai.request(srv.App) as SuperAgentStatic)
.post('/api/user/login')
.post(Config.Client.apiPath + '/user/login')
.send({
loginCredential: {
password: testUser.password,

View File

@ -64,7 +64,7 @@ describe('UserRouter', () => {
const login = async (srv: Server): Promise<any> => {
const result = await (chai.request(srv.App) as SuperAgentStatic)
.post('/api/user/login')
.post(Config.Client.apiPath + '/user/login')
.send({
loginCredential: {
password: testUser.password,
@ -89,7 +89,7 @@ describe('UserRouter', () => {
it('it skip login', async () => {
Config.Client.authenticationRequired = false;
const result = await chai.request(server.App)
.post('/api/user/login');
.post(Config.Client.apiPath + '/user/login');
result.res.should.have.status(404);
});
@ -107,7 +107,7 @@ describe('UserRouter', () => {
const loginRes = await login(server);
const result = await chai.request(server.App)
.get('/api/user/me')
.get(Config.Client.apiPath + '/user/me')
.set('Cookie', loginRes.res.headers['set-cookie'])
.set('CSRF-Token', loginRes.body.result.csrfToken);
@ -118,7 +118,7 @@ describe('UserRouter', () => {
Config.Client.authenticationRequired = true;
const result = await chai.request(server.App)
.get('/api/user/me');
.get(Config.Client.apiPath + '/user/me');
result.res.should.have.status(401);
});
@ -134,7 +134,7 @@ describe('UserRouter', () => {
const q: any = {};
q[QueryParams.gallery.sharingKey_query] = sharingKey;
const result = await chai.request(server.App)
.get('/api/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharingKey)
.get(Config.Client.apiPath + '/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharingKey)
.set('Cookie', loginRes.res.headers['set-cookie'])
.set('CSRF-Token', loginRes.body.result.csrfToken);
@ -152,7 +152,7 @@ describe('UserRouter', () => {
const q: any = {};
q[QueryParams.gallery.sharingKey_query] = sharing.sharingKey;
const result = await chai.request(server.App)
.get('/api/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharing.sharingKey);
.get(Config.Client.apiPath + '/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharing.sharingKey);
checkUserResult(result, RouteTestingHelper.getExpectedSharingUser(sharing));
@ -166,7 +166,7 @@ describe('UserRouter', () => {
const q: any = {};
q[QueryParams.gallery.sharingKey_query] = sharing.sharingKey;
const result = await chai.request(server.App)
.get('/api/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharing.sharingKey);
.get(Config.Client.apiPath + '/user/me?' + QueryParams.gallery.sharingKey_query + '=' + sharing.sharingKey);
result.should.have.status(401);
@ -179,7 +179,7 @@ describe('UserRouter', () => {
Config.Client.authenticationRequired = false;
const result = await chai.request(server.App)
.get('/api/user/me');
.get(Config.Client.apiPath + '/user/me');
const expectedGuestUser = {
name: UserRoles[Config.Client.unAuthenticatedUserRole],

View File

@ -38,7 +38,7 @@ describe('SettingsRouter', () => {
const srv = new Server();
await srv.onStarted.wait();
const result = await chai.request(srv.App)
.get('/api/settings');
.get(Config.Client.apiPath + '/settings');
result.res.should.have.status(200);
result.body.should.be.a('object');