improving sharing
This commit is contained in:
parent
8b090603b6
commit
d591204740
@ -63,12 +63,12 @@ To configure it. Run `PiGallery2` first to create `config.json` file, then edit
|
|||||||
* supporting several core CPU
|
* supporting several core CPU
|
||||||
* supporting hardware acceleration ([sharp](https://github.com/lovell/sharp) and [gm](https://github.com/aheckmann/gm) as optional and JS-based [Jimp](https://github.com/oliver-moran/jimp) as fallback)
|
* supporting hardware acceleration ([sharp](https://github.com/lovell/sharp) and [gm](https://github.com/aheckmann/gm) as optional and JS-based [Jimp](https://github.com/oliver-moran/jimp) as fallback)
|
||||||
* Custom lightbox for full screen photo viewing
|
* Custom lightbox for full screen photo viewing
|
||||||
* keyboard support for navigation - `In progress`
|
* keyboard support for navigation
|
||||||
* showing low-res thumbnail while full image loads
|
* showing low-res thumbnail while full image loads
|
||||||
* Information panel for showing **Exif info** - `In progress`
|
* Information panel for showing **Exif info** - `In progress`
|
||||||
* Client side caching (directories and search results)
|
* Client side caching (directories and search results)
|
||||||
* Rendering **photos** with GPS coordinates **on google map**
|
* Rendering **photos** with GPS coordinates **on google map**
|
||||||
* .gpx file support - `In progress`
|
* .gpx file support - `future plan`
|
||||||
* **Two modes: SQL database and no-database mode**
|
* **Two modes: SQL database and no-database mode**
|
||||||
* both modes supports
|
* both modes supports
|
||||||
* user management
|
* user management
|
||||||
@ -77,11 +77,11 @@ To configure it. Run `PiGallery2` first to create `config.json` file, then edit
|
|||||||
* faster directory listing
|
* faster directory listing
|
||||||
* searching
|
* searching
|
||||||
* instant search, auto complete
|
* instant search, auto complete
|
||||||
* sharing - `In progress`
|
* sharing
|
||||||
* setting link expiration time
|
* setting link expiration time
|
||||||
* Nice design - `In progress`
|
* Nice design - `In progress`
|
||||||
* responsive design (phone, tablet desktop support)
|
* responsive design (phone, tablet desktop support)
|
||||||
* Setup page - `In progress`
|
* Setup page - `In progress`
|
||||||
* **Markdown based blogging support** - `In progress`
|
* **Markdown based blogging support** - `future plan`
|
||||||
* you can write some note in the blog.md for every directory
|
* you can write some note in the blog.md for every directory
|
||||||
* bug free :) - `In progress`
|
* bug free :) - `In progress`
|
||||||
|
|||||||
7
USERRIGHTS.md
Normal file
7
USERRIGHTS.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# User rights
|
||||||
|
|
||||||
|
* Limited Guest - list dir
|
||||||
|
* Guest - +search
|
||||||
|
* User - +share
|
||||||
|
* Admin - +settings
|
||||||
|
* Developer - +see errors
|
||||||
@ -10,7 +10,7 @@ import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
|||||||
import {ProjectPath} from "../ProjectPath";
|
import {ProjectPath} from "../ProjectPath";
|
||||||
import {Logger} from "../Logger";
|
import {Logger} from "../Logger";
|
||||||
import {Config} from "../../common/config/private/Config";
|
import {Config} from "../../common/config/private/Config";
|
||||||
import {UserUtil} from "../../common/entities/UserDTO";
|
import {UserDTO} from "../../common/entities/UserDTO";
|
||||||
|
|
||||||
|
|
||||||
const LOG_TAG = "[GalleryMWs]";
|
const LOG_TAG = "[GalleryMWs]";
|
||||||
@ -32,7 +32,7 @@ export class GalleryMWs {
|
|||||||
req.session.user.permissions.length > 0 &&
|
req.session.user.permissions.length > 0 &&
|
||||||
req.session.user.permissions[0] != "/") {
|
req.session.user.permissions[0] != "/") {
|
||||||
directory.directories = directory.directories.filter(d =>
|
directory.directories = directory.directories.filter(d =>
|
||||||
UserUtil.isDirectoryAvailable(d, req.session.user.permissions));
|
UserDTO.isDirectoryAvailable(d, req.session.user.permissions));
|
||||||
}
|
}
|
||||||
req.resultPipe = new ContentWrapper(directory, null);
|
req.resultPipe = new ContentWrapper(directory, null);
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
///<reference path="../customtypings/ExtendedRequest.d.ts"/>
|
///<reference path="../customtypings/ExtendedRequest.d.ts"/>
|
||||||
import {NextFunction, Request, Response} from "express";
|
import {NextFunction, Request, Response} from "express";
|
||||||
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
||||||
import {UserDTO, UserRoles, UserUtil} from "../../../common/entities/UserDTO";
|
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||||
import {Config} from "../../../common/config/private/Config";
|
import {Config} from "../../../common/config/private/Config";
|
||||||
|
|
||||||
@ -9,12 +9,15 @@ export class AuthenticationMWs {
|
|||||||
|
|
||||||
private static async getSharingUser(req: Request) {
|
private static async getSharingUser(req: Request) {
|
||||||
if (Config.Client.Sharing.enabled === true &&
|
if (Config.Client.Sharing.enabled === true &&
|
||||||
Config.Client.Sharing.passwordProtected === false &&
|
|
||||||
(!!req.query.sk || !!req.params.sharingKey)) {
|
(!!req.query.sk || !!req.params.sharingKey)) {
|
||||||
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
||||||
sharingKey: req.query.sk || req.params.sharingKey,
|
sharingKey: req.query.sk || req.params.sharingKey,
|
||||||
});
|
});
|
||||||
if (!sharing) {
|
if (!sharing || sharing.expires < Date.now()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.Client.Sharing.passwordProtected === true && sharing.password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +25,7 @@ export class AuthenticationMWs {
|
|||||||
if (sharing.includeSubfolders == true) {
|
if (sharing.includeSubfolders == true) {
|
||||||
path += "*";
|
path += "*";
|
||||||
}
|
}
|
||||||
return <UserDTO>{name: "Guest", role: UserRoles.Guest, permissions: [path]};
|
return <UserDTO>{name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]};
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -67,7 +70,7 @@ export class AuthenticationMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const directoryName = req.params.directory || "/";
|
const directoryName = req.params.directory || "/";
|
||||||
if (UserUtil.isPathAvailable(directoryName, req.session.user.permissions) == true) {
|
if (UserDTO.isPathAvailable(directoryName, req.session.user.permissions) == true) {
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -117,6 +120,42 @@ export class AuthenticationMWs {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static async shareLogin(req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
|
if (Config.Client.Sharing.enabled === false) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
//not enough parameter
|
||||||
|
if ((!req.query.sk && !req.params.sharingKey)) {
|
||||||
|
return next(new Error(ErrorCodes.INPUT_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const password = (req.body ? req.body.password : null) || null;
|
||||||
|
|
||||||
|
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
||||||
|
sharingKey: req.query.sk || req.params.sharingKey,
|
||||||
|
});
|
||||||
|
if (!sharing || sharing.expires < Date.now() ||
|
||||||
|
(Config.Client.Sharing.passwordProtected === true && sharing.password !== password)) {
|
||||||
|
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = sharing.path;
|
||||||
|
if (sharing.includeSubfolders == true) {
|
||||||
|
path += "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
req.session.user = <UserDTO>{name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]};
|
||||||
|
return next();
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static logout(req: Request, res: Response, next: NextFunction) {
|
public static logout(req: Request, res: Response, next: NextFunction) {
|
||||||
delete req.session.user;
|
delete req.session.user;
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export class UserManager implements IUserManager {
|
|||||||
this.createUser(<UserDTO>{name: "developer", password: "developer", role: UserRoles.Developer});
|
this.createUser(<UserDTO>{name: "developer", password: "developer", role: UserRoles.Developer});
|
||||||
this.createUser(<UserDTO>{name: "admin", password: "admin", role: UserRoles.Admin});
|
this.createUser(<UserDTO>{name: "admin", password: "admin", role: UserRoles.Admin});
|
||||||
this.createUser(<UserDTO>{name: "user", password: "user", role: UserRoles.User});
|
this.createUser(<UserDTO>{name: "user", password: "user", role: UserRoles.User});
|
||||||
this.createUser(<UserDTO>{name: "guest", password: "guest", role: UserRoles.Guest});
|
this.createUser(<UserDTO>{name: "guest", password: "guest", role: UserRoles.LimitedGuest});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
|||||||
import {GalleryMWs} from "../middlewares/GalleryMWs";
|
import {GalleryMWs} from "../middlewares/GalleryMWs";
|
||||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||||
import {ThumbnailGeneratorMWs} from "../middlewares/thumbnail/ThumbnailGeneratorMWs";
|
import {ThumbnailGeneratorMWs} from "../middlewares/thumbnail/ThumbnailGeneratorMWs";
|
||||||
|
import {UserRoles} from "../../common/entities/UserDTO";
|
||||||
|
|
||||||
export class GalleryRouter {
|
export class GalleryRouter {
|
||||||
public static route(app: any) {
|
public static route(app: any) {
|
||||||
@ -31,6 +32,7 @@ export class GalleryRouter {
|
|||||||
private static addGetImage(app) {
|
private static addGetImage(app) {
|
||||||
app.get(["/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"],
|
app.get(["/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"],
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
//TODO: authorize path
|
||||||
GalleryMWs.loadImage,
|
GalleryMWs.loadImage,
|
||||||
RenderingMWs.renderFile
|
RenderingMWs.renderFile
|
||||||
);
|
);
|
||||||
@ -39,6 +41,7 @@ export class GalleryRouter {
|
|||||||
private static addGetImageThumbnail(app) {
|
private static addGetImageThumbnail(app) {
|
||||||
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?",
|
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
//TODO: authorize path
|
||||||
GalleryMWs.loadImage,
|
GalleryMWs.loadImage,
|
||||||
ThumbnailGeneratorMWs.generateThumbnail,
|
ThumbnailGeneratorMWs.generateThumbnail,
|
||||||
RenderingMWs.renderFile
|
RenderingMWs.renderFile
|
||||||
@ -48,6 +51,7 @@ export class GalleryRouter {
|
|||||||
private static addGetImageIcon(app) {
|
private static addGetImageIcon(app) {
|
||||||
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon",
|
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
//TODO: authorize path
|
||||||
GalleryMWs.loadImage,
|
GalleryMWs.loadImage,
|
||||||
ThumbnailGeneratorMWs.generateIcon,
|
ThumbnailGeneratorMWs.generateIcon,
|
||||||
RenderingMWs.renderFile
|
RenderingMWs.renderFile
|
||||||
@ -57,6 +61,7 @@ export class GalleryRouter {
|
|||||||
private static addSearch(app) {
|
private static addSearch(app) {
|
||||||
app.get("/api/search/:text",
|
app.get("/api/search/:text",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
GalleryMWs.search,
|
GalleryMWs.search,
|
||||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||||
GalleryMWs.removeCyclicDirectoryReferences,
|
GalleryMWs.removeCyclicDirectoryReferences,
|
||||||
@ -67,6 +72,7 @@ export class GalleryRouter {
|
|||||||
private static addInstantSearch(app) {
|
private static addInstantSearch(app) {
|
||||||
app.get("/api/instant-search/:text",
|
app.get("/api/instant-search/:text",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
GalleryMWs.instantSearch,
|
GalleryMWs.instantSearch,
|
||||||
ThumbnailGeneratorMWs.addThumbnailInformation,
|
ThumbnailGeneratorMWs.addThumbnailInformation,
|
||||||
GalleryMWs.removeCyclicDirectoryReferences,
|
GalleryMWs.removeCyclicDirectoryReferences,
|
||||||
@ -77,6 +83,7 @@ export class GalleryRouter {
|
|||||||
private static addAutoComplete(app) {
|
private static addAutoComplete(app) {
|
||||||
app.get("/api/autocomplete/:text",
|
app.get("/api/autocomplete/:text",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
GalleryMWs.autocomplete,
|
GalleryMWs.autocomplete,
|
||||||
RenderingMWs.renderResult
|
RenderingMWs.renderResult
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,15 +6,24 @@ import {SharingMWs} from "../middlewares/SharingMWs";
|
|||||||
export class SharingRouter {
|
export class SharingRouter {
|
||||||
public static route(app: any) {
|
public static route(app: any) {
|
||||||
|
|
||||||
|
this.addShareLogin(app);
|
||||||
this.addGetSharing(app);
|
this.addGetSharing(app);
|
||||||
this.addCreateSharing(app);
|
this.addCreateSharing(app);
|
||||||
this.addUpdateSharing(app);
|
this.addUpdateSharing(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static addShareLogin(app) {
|
||||||
|
app.post("/api/share/login",
|
||||||
|
AuthenticationMWs.inverseAuthenticate,
|
||||||
|
AuthenticationMWs.shareLogin,
|
||||||
|
RenderingMWs.renderSessionUser
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
private static addGetSharing(app) {
|
private static addGetSharing(app) {
|
||||||
app.get("/api/share/:sharingKey",
|
app.get("/api/share/:sharingKey",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
AuthenticationMWs.authorise(UserRoles.LimitedGuest),
|
||||||
SharingMWs.getSharing,
|
SharingMWs.getSharing,
|
||||||
RenderingMWs.renderSharing
|
RenderingMWs.renderSharing
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,7 +8,13 @@ declare module ServerInject {
|
|||||||
|
|
||||||
export let Config = new PublicConfigClass();
|
export let Config = new PublicConfigClass();
|
||||||
|
|
||||||
|
|
||||||
if (typeof ServerInject !== "undefined" && typeof ServerInject.ConfigInject !== "undefined") {
|
if (typeof ServerInject !== "undefined" && typeof ServerInject.ConfigInject !== "undefined") {
|
||||||
WebConfigLoader.loadFrontendConfig(Config.Client, ServerInject.ConfigInject);
|
WebConfigLoader.loadFrontendConfig(Config.Client, ServerInject.ConfigInject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Config.Client.publicUrl == "") {
|
||||||
|
Config.Client.publicUrl = location.origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@ export interface ClientConfig {
|
|||||||
enableOnScrollThumbnailPrioritising: boolean;
|
enableOnScrollThumbnailPrioritising: boolean;
|
||||||
authenticationRequired: boolean;
|
authenticationRequired: boolean;
|
||||||
googleApiKey: string;
|
googleApiKey: string;
|
||||||
|
publicUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +47,8 @@ export class PublicConfigClass {
|
|||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
enableOnScrollThumbnailPrioritising: true,
|
enableOnScrollThumbnailPrioritising: true,
|
||||||
authenticationRequired: true,
|
authenticationRequired: true,
|
||||||
googleApiKey: ""
|
googleApiKey: "",
|
||||||
|
publicUrl: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,8 @@ export interface DirectoryDTO {
|
|||||||
photos: Array<PhotoDTO>;
|
photos: Array<PhotoDTO>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export module DirectoryUtil {
|
export module DirectoryDTO {
|
||||||
export const addReferences = (dir: DirectoryDTO) => {
|
export const addReferences = (dir: DirectoryDTO): void => {
|
||||||
dir.photos.forEach((photo: PhotoDTO) => {
|
dir.photos.forEach((photo: PhotoDTO) => {
|
||||||
photo.directory = dir;
|
photo.directory = dir;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import {DirectoryDTO} from "./DirectoryDTO";
|
import {DirectoryDTO} from "./DirectoryDTO";
|
||||||
import {Utils} from "../Utils";
|
import {Utils} from "../Utils";
|
||||||
export enum UserRoles{
|
export enum UserRoles{
|
||||||
Guest = 0,
|
LimitedGuest = 0,
|
||||||
TrustedGuest = 1,
|
Guest = 1,
|
||||||
User = 2,
|
User = 2,
|
||||||
Admin = 3,
|
Admin = 3,
|
||||||
Developer = 4,
|
Developer = 4,
|
||||||
@ -17,7 +17,7 @@ export interface UserDTO {
|
|||||||
permissions: string[]; //user can only see these permissions. if ends with *, its recursive
|
permissions: string[]; //user can only see these permissions. if ends with *, its recursive
|
||||||
}
|
}
|
||||||
|
|
||||||
export module UserUtil {
|
export module UserDTO {
|
||||||
|
|
||||||
export const isPathAvailable = (path: string, permissions: string[]): boolean => {
|
export const isPathAvailable = (path: string, permissions: string[]): boolean => {
|
||||||
if (permissions == null || permissions.length == 0 || permissions[0] == "/") {
|
if (permissions == null || permissions.length == 0 || permissions[0] == "/") {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import {Router} from "@angular/router";
|
|||||||
import {Config} from "../../common/config/public/Config";
|
import {Config} from "../../common/config/public/Config";
|
||||||
import {Title} from "@angular/platform-browser";
|
import {Title} from "@angular/platform-browser";
|
||||||
import {NotificationService} from "./model/notification.service";
|
import {NotificationService} from "./model/notification.service";
|
||||||
|
import {ShareService} from "./gallery/share.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -16,23 +17,23 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private _router: Router,
|
constructor(private _router: Router,
|
||||||
private _authenticationService: AuthenticationService,
|
private _authenticationService: AuthenticationService,
|
||||||
|
private _shareService: ShareService,
|
||||||
private _title: Title, vcr: ViewContainerRef,
|
private _title: Title, vcr: ViewContainerRef,
|
||||||
notificatin: NotificationService) {
|
notificatin: NotificationService) {
|
||||||
notificatin.setRootViewContainerRef(vcr);
|
notificatin.setRootViewContainerRef(vcr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
async ngOnInit() {
|
||||||
this._title.setTitle(Config.Client.applicationTitle);
|
this._title.setTitle(Config.Client.applicationTitle);
|
||||||
|
await this._shareService.wait();
|
||||||
this._authenticationService.user.subscribe((user: UserDTO) => {
|
this._authenticationService.user.subscribe((user: UserDTO) => {
|
||||||
if (user != null) {
|
if (this._authenticationService.isAuthenticated()) {
|
||||||
if (this._router.isActive('login', true)) {
|
if (this.isLoginPage()) {
|
||||||
console.log("routing");
|
return this.toGallery();
|
||||||
this._router.navigate(["gallery", ""]);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this._router.isActive('login', true)) {
|
if (!this.isLoginPage()) {
|
||||||
console.log("routing");
|
return this.toLogin();
|
||||||
this._router.navigate(["login"]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,5 +42,23 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isLoginPage() {
|
||||||
|
return this._router.isActive('login', true) || this._router.isActive('shareLogin', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private toLogin() {
|
||||||
|
if (this._shareService.isSharing()) {
|
||||||
|
return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||||
|
} else {
|
||||||
|
return this._router.navigate(["login"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private toGallery() {
|
||||||
|
if (this._shareService.isSharing()) {
|
||||||
|
return this._router.navigate(["share", this._shareService.getSharingKey()]);
|
||||||
|
} else {
|
||||||
|
return this._router.navigate(["gallery", ""]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,9 @@ import {ToastModule} from "ng2-toastr/ng2-toastr";
|
|||||||
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
||||||
import {NotificationService} from "./model/notification.service";
|
import {NotificationService} from "./model/notification.service";
|
||||||
|
|
||||||
|
import {ClipboardModule} from "ngx-clipboard";
|
||||||
|
import {NavigationService} from "./model/navigation.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleMapsConfig {
|
export class GoogleMapsConfig {
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
@ -58,6 +61,7 @@ export class GoogleMapsConfig {
|
|||||||
HttpModule,
|
HttpModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
appRoutes,
|
appRoutes,
|
||||||
|
ClipboardModule,
|
||||||
ToastModule.forRoot(),
|
ToastModule.forRoot(),
|
||||||
ModalModule.forRoot(),
|
ModalModule.forRoot(),
|
||||||
AgmCoreModule.forRoot(),
|
AgmCoreModule.forRoot(),
|
||||||
@ -98,6 +102,7 @@ export class GoogleMapsConfig {
|
|||||||
ThumbnailManagerService,
|
ThumbnailManagerService,
|
||||||
NotificationService,
|
NotificationService,
|
||||||
FullScreenService,
|
FullScreenService,
|
||||||
|
NavigationService,
|
||||||
OverlayService],
|
OverlayService],
|
||||||
|
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {Injectable} from "@angular/core";
|
import {Injectable} from "@angular/core";
|
||||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||||
import {DirectoryDTO, DirectoryUtil} from "../../../common/entities/DirectoryDTO";
|
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||||
import {Utils} from "../../../common/Utils";
|
import {Utils} from "../../../common/Utils";
|
||||||
import {Config} from "../../../common/config/public/Config";
|
import {Config} from "../../../common/config/public/Config";
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export class GalleryCacheService {
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
let directory: DirectoryDTO = JSON.parse(value);
|
let directory: DirectoryDTO = JSON.parse(value);
|
||||||
|
|
||||||
DirectoryUtil.addReferences(directory);
|
DirectoryDTO.addReferences(directory);
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -2,6 +2,12 @@
|
|||||||
<app-frame>
|
<app-frame>
|
||||||
|
|
||||||
<ng-container navbar>
|
<ng-container navbar>
|
||||||
|
|
||||||
|
<li *ngIf="countDown">
|
||||||
|
<p class="navbar-text">Link availability: {{countDown.day}} days,
|
||||||
|
{{("0"+countDown.hour).slice(-2)}}:{{("0"+countDown.minute).slice(-2)}}:{{("0"+countDown.second).slice(-2)}}
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
<li *ngIf="showSearchBar">
|
<li *ngIf="showSearchBar">
|
||||||
<gallery-search #search></gallery-search>
|
<gallery-search #search></gallery-search>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -9,6 +9,9 @@ import {Config} from "../../../common/config/public/Config";
|
|||||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||||
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
||||||
import {ShareService} from "./share.service";
|
import {ShareService} from "./share.service";
|
||||||
|
import {NavigationService} from "../model/navigation.service";
|
||||||
|
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||||
|
import {Observable} from "rxjs/Rx";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'gallery',
|
selector: 'gallery',
|
||||||
@ -20,42 +23,61 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
@ViewChild(GallerySearchComponent) search: GallerySearchComponent;
|
@ViewChild(GallerySearchComponent) search: GallerySearchComponent;
|
||||||
@ViewChild(GalleryGridComponent) grid: GalleryGridComponent;
|
@ViewChild(GalleryGridComponent) grid: GalleryGridComponent;
|
||||||
|
|
||||||
public showSearchBar: boolean = true;
|
public showSearchBar: boolean = false;
|
||||||
public showShare: boolean = true;
|
public showShare: boolean = false;
|
||||||
public directories: DirectoryDTO[] = [];
|
public directories: DirectoryDTO[] = [];
|
||||||
public isPhotoWithLocation = false;
|
public isPhotoWithLocation = false;
|
||||||
|
private $counter;
|
||||||
private subscription = {
|
private subscription = {
|
||||||
content: null,
|
content: null,
|
||||||
route: null
|
route: null,
|
||||||
|
timer: null
|
||||||
};
|
};
|
||||||
|
public countDown = null;
|
||||||
|
|
||||||
constructor(public _galleryService: GalleryService,
|
constructor(public _galleryService: GalleryService,
|
||||||
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) {
|
||||||
|
|
||||||
this.showSearchBar = Config.Client.Search.searchEnabled;
|
|
||||||
this.showShare = Config.Client.Sharing.enabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTimer(t: number) {
|
||||||
ngOnInit() {
|
if (this.shareService.sharing.value == null) {
|
||||||
if (!this._authService.isAuthenticated() &&
|
|
||||||
(!this.shareService.isSharing() ||
|
|
||||||
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))
|
|
||||||
) {
|
|
||||||
if (this.shareService.isSharing()) {
|
|
||||||
this._router.navigate(['shareLogin']);
|
|
||||||
} else {
|
|
||||||
this._router.navigate(['login']);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
t = Math.floor((this.shareService.sharing.value.expires - Date.now()) / 1000);
|
||||||
|
this.countDown = {};
|
||||||
|
this.countDown.day = Math.floor(t / 86400);
|
||||||
|
t -= this.countDown.day * 86400;
|
||||||
|
this.countDown.hour = Math.floor(t / 3600) % 24;
|
||||||
|
t -= this.countDown.hour * 3600;
|
||||||
|
this.countDown.minute = Math.floor(t / 60) % 60;
|
||||||
|
t -= this.countDown.minute * 60;
|
||||||
|
this.countDown.second = t % 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
await this.shareService.wait();
|
||||||
|
if (!this._authService.isAuthenticated() &&
|
||||||
|
(!this.shareService.isSharing() ||
|
||||||
|
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))) {
|
||||||
|
|
||||||
|
return this._navigation.toLogin();
|
||||||
|
}
|
||||||
|
this.showSearchBar = Config.Client.Search.searchEnabled && this._authService.isAuthorized(UserRoles.Guest);
|
||||||
|
this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User);
|
||||||
|
|
||||||
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
|
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
|
||||||
this.subscription.route = this._route.params.subscribe(this.onRoute);
|
this.subscription.route = this._route.params.subscribe(this.onRoute);
|
||||||
|
|
||||||
|
if (this.shareService.isSharing()) {
|
||||||
|
this.$counter = Observable.interval(1000);
|
||||||
|
this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -109,7 +131,7 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params['sharingKey'] && params['sharingKey'] != "") {
|
if (params['sharingKey'] && params['sharingKey'] != "") {
|
||||||
const sharing = await this._galleryService.getSharing(this.shareService.getSharingKey());
|
const sharing = await this.shareService.getSharing();
|
||||||
this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}});
|
this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
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 {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||||
import {DirectoryDTO, DirectoryUtil} from "../../../common/entities/DirectoryDTO";
|
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||||
import {GalleryCacheService} from "./cache.gallery.service";
|
import {GalleryCacheService} from "./cache.gallery.service";
|
||||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||||
@ -53,7 +53,7 @@ export class GalleryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DirectoryUtil.addReferences(cw.directory);
|
DirectoryDTO.addReferences(cw.directory);
|
||||||
|
|
||||||
|
|
||||||
this.lastDirectory = cw.directory;
|
this.lastDirectory = cw.directory;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import {Component, Input, OnChanges} from "@angular/core";
|
import {Component, Input, OnChanges} from "@angular/core";
|
||||||
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
||||||
import {RouterLink} from "@angular/router";
|
import {RouterLink} from "@angular/router";
|
||||||
import {UserUtil} from "../../../../common/entities/UserDTO";
|
import {UserDTO} from "../../../../common/entities/UserDTO";
|
||||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||||
import {ShareService} from "../share.service";
|
import {ShareService} from "../share.service";
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export class GalleryNavigatorComponent implements OnChanges {
|
|||||||
if (dirs.length == 0) {
|
if (dirs.length == 0) {
|
||||||
arr.push({name: "Images", route: null});
|
arr.push({name: "Images", route: null});
|
||||||
} else {
|
} else {
|
||||||
arr.push({name: "Images", route: UserUtil.isPathAvailable("/", user.permissions) ? "/" : null});
|
arr.push({name: "Images", route: UserDTO.isPathAvailable("/", user.permissions) ? "/" : null});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export class GalleryNavigatorComponent implements OnChanges {
|
|||||||
if (dirs.length - 1 == index) {
|
if (dirs.length - 1 == index) {
|
||||||
arr.push({name: name, route: null});
|
arr.push({name: name, route: null});
|
||||||
} else {
|
} else {
|
||||||
arr.push({name: name, route: UserUtil.isPathAvailable(route, user.permissions) ? route : null});
|
arr.push({name: name, route: UserDTO.isPathAvailable(route, user.permissions) ? route : null});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,12 @@ 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} from "../../../common/entities/SharingDTO";
|
||||||
import {Router, RoutesRecognized} from "@angular/router";
|
import {Router, RoutesRecognized} from "@angular/router";
|
||||||
|
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ShareService {
|
export class ShareService {
|
||||||
|
|
||||||
|
public sharing: BehaviorSubject<SharingDTO>;
|
||||||
param = null;
|
param = null;
|
||||||
queryParam = null;
|
queryParam = null;
|
||||||
sharingKey = null;
|
sharingKey = null;
|
||||||
@ -15,7 +17,7 @@ export class ShareService {
|
|||||||
|
|
||||||
|
|
||||||
constructor(private _networkService: NetworkService, private router: Router) {
|
constructor(private _networkService: NetworkService, private router: Router) {
|
||||||
|
this.sharing = new BehaviorSubject(null);
|
||||||
this.ReadyPR = new Promise((resolve) => {
|
this.ReadyPR = new Promise((resolve) => {
|
||||||
if (this.inited == true) {
|
if (this.inited == true) {
|
||||||
return resolve();
|
return resolve();
|
||||||
@ -27,7 +29,11 @@ export class ShareService {
|
|||||||
if (val instanceof RoutesRecognized) {
|
if (val instanceof RoutesRecognized) {
|
||||||
this.param = val.state.root.firstChild.params["sharingKey"] || null;
|
this.param = val.state.root.firstChild.params["sharingKey"] || null;
|
||||||
this.queryParam = val.state.root.firstChild.queryParams["sk"] || null;
|
this.queryParam = val.state.root.firstChild.queryParams["sk"] || null;
|
||||||
this.sharingKey = this.param || this.queryParam;
|
const changed = this.sharingKey != this.param || this.queryParam;
|
||||||
|
if (changed) {
|
||||||
|
this.sharingKey = this.param || this.queryParam;
|
||||||
|
this.getSharing();
|
||||||
|
}
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve();
|
this.resolve();
|
||||||
this.inited = true;
|
this.inited = true;
|
||||||
@ -43,7 +49,7 @@ export class ShareService {
|
|||||||
return this.ReadyPR;
|
return this.ReadyPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSharing(dir: string, includeSubfolders: boolean, valid: number): Promise<SharingDTO> {
|
public createSharing(dir: string, includeSubfolders: boolean, valid: number): Promise<SharingDTO> {
|
||||||
return this._networkService.postJson("/share/" + dir, {
|
return this._networkService.postJson("/share/" + dir, {
|
||||||
createSharing: <CreateSharingDTO>{
|
createSharing: <CreateSharingDTO>{
|
||||||
includeSubfolders: includeSubfolders,
|
includeSubfolders: includeSubfolders,
|
||||||
@ -70,4 +76,10 @@ export class ShareService {
|
|||||||
return this.sharingKey != null;
|
return this.sharingKey != null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getSharing(): Promise<SharingDTO> {
|
||||||
|
const sharing = await this._networkService.getJson<SharingDTO>("/share/" + this.getSharingKey());
|
||||||
|
this.sharing.next(sharing);
|
||||||
|
return sharing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,11 @@
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.full-width {
|
||||||
padding-left: 0;
|
width: 100%;
|
||||||
padding-right: 0;
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
padding-top: 1px;
|
||||||
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,70 +1,98 @@
|
|||||||
<button id="shareButton" class="btn btn-default navbar-btn btn-link" type="button"
|
<button id="shareButton" class="btn btn-default navbar-btn btn-link"
|
||||||
data-toggle="modal" data-target="#shareModal" [disabled]="!enabled" (click)="get()">
|
type="button" [disabled]="!enabled" (click)="showModal()">
|
||||||
<span class="glyphicon glyphicon-share-alt"></span>
|
<span class="glyphicon glyphicon-share-alt"></span>
|
||||||
Share
|
Share
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- sharing Modal-->
|
<!-- sharing Modal-->
|
||||||
<div class="modal fade" id="shareModal" tabindex="-1" role="dialog" aria-labelledby="shareModalLabel"
|
<div bsModal #shareModal="bs-modal"
|
||||||
data-backdrop="false"
|
class="modal fade" id="shareModal"
|
||||||
|
tabindex="-1" role="dialog" aria-labelledby="shareModalLabel"
|
||||||
|
[config]="{ backdrop: false }"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
<button type="button" class="close" (click)="shareModal.hide()" aria-label="Close"><span
|
||||||
aria-hidden="true">×</span></button>
|
aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="shareModalLabel">Share</h4>
|
<h4 class="modal-title" id="shareModalLabel">Share</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input id="shareLink" name="shareLink" placeholder="link" class="form-control input-md" type="text"
|
<input id="shareLink"
|
||||||
|
name="shareLink"
|
||||||
|
placeholder="link"
|
||||||
|
class="form-control input-md"
|
||||||
|
type="text"
|
||||||
[ngModel]="url">
|
[ngModel]="url">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2 pull-right">
|
<div class="col-sm-2 pull-right">
|
||||||
<button id="copyButton" name="copyButton" data-clipboard-target="shareLink" class="btn btn-primary">Copy
|
<button id="copyButton" name="copyButton"
|
||||||
|
ngxClipboard [cbContent]="url"
|
||||||
|
(cbOnSuccess)="onCopy()"
|
||||||
|
class="btn btn-primary">Copy
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="form-horizontal">
|
<div class="row">
|
||||||
<div class="form-group" style="padding: 0 15px 0 15px;">
|
<div class="col-sm-2">
|
||||||
|
<label class="control-label">Sharing:</label>
|
||||||
<div style="display: inline;">
|
</div>
|
||||||
<label class="control-label">sharing:</label>
|
<div class="col-sm-10">
|
||||||
<div class="form-control-static" id="sharingPath">{{currentDir}}</div>
|
<input disabled type="text"
|
||||||
</div>
|
class="full-width form-control"
|
||||||
|
[ngModel]="currentDir">
|
||||||
<label class="checkbox pull-right">
|
|
||||||
<input id="recursiveShareBox" type="checkbox" (change)="update()" [(ngModel)]="input.includeSubfolders"
|
|
||||||
checked="true" value="remember-me"> Include subfolders
|
|
||||||
</label>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-2">
|
||||||
Valid:
|
<label class="control-label">Include subfolders:</label>
|
||||||
<p id="sliderText"></p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input id="shareSlider" data-slider-id='shareSlider' [(ngModel)]="input.valid.amount" (change)="update()"
|
<input id="recursiveShareBox"
|
||||||
|
type="checkbox"
|
||||||
|
(change)="update()"
|
||||||
|
[(ngModel)]="input.includeSubfolders"
|
||||||
|
checked="checked"
|
||||||
|
value="remember-me">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label class="control-label">Password:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input id="password"
|
||||||
|
class="form-control"
|
||||||
|
type="password"
|
||||||
|
(change)="update()"
|
||||||
|
[(ngModel)]="input.password"
|
||||||
|
placeholder="Password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label class="control-label">Valid:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3" style="padding-right: 1px">
|
||||||
|
<input class="form-control" [(ngModel)]="input.valid.amount" (change)="update()"
|
||||||
name="validAmount"
|
name="validAmount"
|
||||||
type="number" min="0" step="1"/>
|
type="number" min="0" step="1"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-3" style="padding-left: 1px">
|
||||||
<select class="form-control" [(ngModel)]="input.valid.type" (change)="update()" name="validType" required>
|
<select class="form-control col-md-3" [(ngModel)]="input.valid.type" (change)="update()" name="validType"
|
||||||
|
required>
|
||||||
<option *ngFor="let repository of validityTypes" [value]="repository.key">{{repository.value}}
|
<option *ngFor="let repository of validityTypes" [value]="repository.key">{{repository.value}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-2 col-sm-push-10">
|
|
||||||
<button id="updatebutton" name="updatebutton" class="btn btn-primary">Update</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
import {Component, OnDestroy, OnInit} from "@angular/core";
|
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||||
import {Utils} from "../../../../common/Utils";
|
import {Utils} from "../../../../common/Utils";
|
||||||
import {ShareService} from "../share.service";
|
import {ShareService} from "../share.service";
|
||||||
import {GalleryService} from "../gallery.service";
|
import {GalleryService} from "../gallery.service";
|
||||||
import {ContentWrapper} from "../../../../common/entities/ConentWrapper";
|
import {ContentWrapper} from "../../../../common/entities/ConentWrapper";
|
||||||
import {SharingDTO} from "../../../../common/entities/SharingDTO";
|
import {SharingDTO} from "../../../../common/entities/SharingDTO";
|
||||||
|
import {ModalDirective} from "ngx-bootstrap/modal";
|
||||||
|
import {Config} from "../../../../common/config/public/Config";
|
||||||
|
import {NotificationService} from "../../model/notification.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'gallery-share',
|
selector: 'gallery-share',
|
||||||
@ -11,6 +15,7 @@ import {SharingDTO} from "../../../../common/entities/SharingDTO";
|
|||||||
styleUrls: ['./share.gallery.component.css'],
|
styleUrls: ['./share.gallery.component.css'],
|
||||||
})
|
})
|
||||||
export class GalleryShareComponent implements OnInit, OnDestroy {
|
export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild('shareModal') public childModal: ModalDirective;
|
||||||
|
|
||||||
enabled: boolean = true;
|
enabled: boolean = true;
|
||||||
url: string = "";
|
url: string = "";
|
||||||
@ -26,8 +31,11 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
currentDir: string = "";
|
currentDir: string = "";
|
||||||
sharing: SharingDTO;
|
sharing: SharingDTO;
|
||||||
contentSubscription = null;
|
contentSubscription = null;
|
||||||
|
passwordProtection = false;
|
||||||
|
|
||||||
constructor(private _sharingService: ShareService, public _galleryService: GalleryService) {
|
constructor(private _sharingService: ShareService,
|
||||||
|
public _galleryService: GalleryService,
|
||||||
|
private _notification: NotificationService) {
|
||||||
this.validityTypes = Utils.enumToArray(ValidityTypes);
|
this.validityTypes = Utils.enumToArray(ValidityTypes);
|
||||||
|
|
||||||
|
|
||||||
@ -42,6 +50,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
this.currentDir = Utils.concatUrls(content.directory.path, content.directory.name);
|
this.currentDir = Utils.concatUrls(content.directory.path, content.directory.name);
|
||||||
});
|
});
|
||||||
|
this.passwordProtection = Config.Client.Sharing.passwordProtected;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -68,14 +77,23 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
this.url = "loading..";
|
this.url = "loading..";
|
||||||
this.sharing = await this._sharingService.updateSharing(this.currentDir, this.sharing.id, this.input.includeSubfolders, this.calcValidity());
|
this.sharing = await this._sharingService.updateSharing(this.currentDir, this.sharing.id, this.input.includeSubfolders, this.calcValidity());
|
||||||
console.log(this.sharing);
|
console.log(this.sharing);
|
||||||
this.url = location.origin + "/share/" + this.sharing.sharingKey
|
this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey
|
||||||
}
|
}
|
||||||
|
|
||||||
async get() {
|
async get() {
|
||||||
this.url = "loading..";
|
this.url = "loading..";
|
||||||
this.sharing = await this._sharingService.getSharing(this.currentDir, this.input.includeSubfolders, this.calcValidity());
|
this.sharing = await this._sharingService.createSharing(this.currentDir, this.input.includeSubfolders, this.calcValidity());
|
||||||
console.log(this.sharing);
|
console.log(this.sharing);
|
||||||
this.url = location.origin + "/share/" + this.sharing.sharingKey
|
this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey
|
||||||
|
}
|
||||||
|
|
||||||
|
async showModal() {
|
||||||
|
await this.get();
|
||||||
|
this.childModal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCopy() {
|
||||||
|
this._notification.success("Url has been copied to clipboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,43 +52,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="login mat-typography" fxLayoutGap="80px" fxLayoutAlign="start center" fxFlexFill fxLayout="column">
|
|
||||||
<h1><img src="assets/icon.png">PiGallery 2</h1>
|
|
||||||
<form class="form-signin" #LoginForm="ngForm" (submit)="onLogin()" fxLayout="row">
|
|
||||||
<md-card fxFlex="400px">
|
|
||||||
<md-card-header>
|
|
||||||
<md-card-title>Please sign in</md-card-title>
|
|
||||||
</md-card-header>
|
|
||||||
<md-card-content fxFlexFill fxLayoutAlign="center center" fxLayout="column">
|
|
||||||
<div *ngIf="loginError">
|
|
||||||
{{loginError}}
|
|
||||||
</div>
|
|
||||||
<md-input-container>
|
|
||||||
<input fxFlexFill mdInput autofocus [(ngModel)]="loginCredential.username" name="name" required>
|
|
||||||
<md-placeholder>
|
|
||||||
<i class="material-icons app-input-icon">face</i> Username
|
|
||||||
</md-placeholder>
|
|
||||||
</md-input-container>
|
|
||||||
<md-input-container>
|
|
||||||
<input fxFlexFill mdInput type="password" [(ngModel)]="loginCredential.password" name="password" required>
|
|
||||||
<md-placeholder>
|
|
||||||
<i class="material-icons app-input-icon">lock_open</i> Password
|
|
||||||
</md-placeholder>
|
|
||||||
</md-input-container>
|
|
||||||
<div fxLayout="row" fxLayoutAlign="start center">
|
|
||||||
<md-checkbox [(ngModel)]="loginCredential.rememberM">Remember me</md-checkbox>
|
|
||||||
</div>
|
|
||||||
</md-card-content>
|
|
||||||
<md-card-actions fxLayout="row" fxLayoutAlign="end center">
|
|
||||||
<button md-raised-button color="primary"
|
|
||||||
[disabled]="!LoginForm.form.valid"
|
|
||||||
type="submit"
|
|
||||||
name="action">Login
|
|
||||||
</button>
|
|
||||||
</md-card-actions>
|
|
||||||
</md-card>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import {Component, OnInit} from "@angular/core";
|
import {Component, OnInit} from "@angular/core";
|
||||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
||||||
import {AuthenticationService} from "../model/network/authentication.service";
|
import {AuthenticationService} from "../model/network/authentication.service";
|
||||||
import {Router} from "@angular/router";
|
|
||||||
import {ErrorCodes} from "../../../common/entities/Error";
|
import {ErrorCodes} from "../../../common/entities/Error";
|
||||||
import {Config} from "../../../common/config/public/Config";
|
import {Config} from "../../../common/config/public/Config";
|
||||||
|
import {NavigationService} from "../model/navigation.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'login',
|
selector: 'login',
|
||||||
@ -15,14 +15,14 @@ export class LoginComponent implements OnInit {
|
|||||||
loginError: any = null;
|
loginError: any = null;
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService, private _router: Router) {
|
constructor(private _authService: AuthenticationService, private _navigation: NavigationService) {
|
||||||
this.loginCredential = new LoginCredential();
|
this.loginCredential = new LoginCredential();
|
||||||
this.title = Config.Client.applicationTitle;
|
this.title = Config.Client.applicationTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this._authService.isAuthenticated()) {
|
if (this._authService.isAuthenticated()) {
|
||||||
this._router.navigate(['gallery', "/"]);
|
this._navigation.toGallery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
frontend/app/model/navigation.service.ts
Normal file
38
frontend/app/model/navigation.service.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import {Injectable} from "@angular/core";
|
||||||
|
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
import {ShareService} from "../gallery/share.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class NavigationService {
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private _router: Router,
|
||||||
|
private _shareService: ShareService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public isLoginPage() {
|
||||||
|
return this._router.isActive('login', true) || this._router.isActive('shareLogin', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toLogin() {
|
||||||
|
console.log("toLogin");
|
||||||
|
await this._shareService.wait();
|
||||||
|
if (this._shareService.isSharing()) {
|
||||||
|
return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||||
|
} else {
|
||||||
|
return this._router.navigate(["login"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toGallery() {
|
||||||
|
console.log("toGallery");
|
||||||
|
await this._shareService.wait();
|
||||||
|
if (this._shareService.isSharing()) {
|
||||||
|
return this._router.navigate(["gallery", ""], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||||
|
} else {
|
||||||
|
return this._router.navigate(["gallery", ""]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -43,9 +43,16 @@ export class AuthenticationService {
|
|||||||
|
|
||||||
|
|
||||||
public async login(credential: LoginCredential): Promise<UserDTO> {
|
public async login(credential: LoginCredential): Promise<UserDTO> {
|
||||||
const user = await this._userService.login(credential);
|
const user = await this._userService.login(credential);
|
||||||
this.user.next(user);
|
this.user.next(user);
|
||||||
return user;
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async shareLogin(password: string): Promise<UserDTO> {
|
||||||
|
const user = await this._userService.shareLogin(password);
|
||||||
|
this.user.next(user);
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +63,9 @@ export class AuthenticationService {
|
|||||||
return !!(this.user.value && this.user.value != null);
|
return !!(this.user.value && this.user.value != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isAuthorized(role: UserRoles) {
|
||||||
|
return this.user.value && this.user.value.role >= role;
|
||||||
|
}
|
||||||
|
|
||||||
public logout() {
|
public logout() {
|
||||||
this._userService.logout();
|
this._userService.logout();
|
||||||
|
|||||||
@ -18,7 +18,11 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public login(credential: LoginCredential): Promise<UserDTO> {
|
public login(credential: LoginCredential): Promise<UserDTO> {
|
||||||
return this._networkService.postJson("/user/login", {"loginCredential": credential});
|
return this._networkService.postJson<UserDTO>("/user/login", {"loginCredential": credential});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async shareLogin(password: string): Promise<UserDTO> {
|
||||||
|
return this._networkService.postJson<UserDTO>("/share/login?sk=" + this._shareService.getSharingKey(), {"password": password});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSessionUser(): Promise<UserDTO> {
|
public async getSessionUser(): Promise<UserDTO> {
|
||||||
|
|||||||
@ -1,12 +1,21 @@
|
|||||||
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 {DataBaseConfig, IPrivateConfig} from "../../../../common/config/private/IPrivateConfig";
|
import {DataBaseConfig, IPrivateConfig} from "../../../../common/config/private/IPrivateConfig";
|
||||||
|
import {NavigationService} from "../../model/navigation.service";
|
||||||
|
import {UserRoles} from "../../../../common/entities/UserDTO";
|
||||||
|
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DatabaseSettingsService {
|
export class DatabaseSettingsService {
|
||||||
|
|
||||||
|
|
||||||
constructor(private _networkService: NetworkService) {
|
constructor(private _networkService: NetworkService, private _authService: AuthenticationService, private _navigation: NavigationService) {
|
||||||
|
|
||||||
|
if (!this._authService.isAuthenticated() ||
|
||||||
|
this._authService.user.value.role < UserRoles.Admin) {
|
||||||
|
this._navigation.toLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSettings(): Promise<DataBaseConfig> {
|
public async getSettings(): Promise<DataBaseConfig> {
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import {Component, OnInit, ViewChild} from "@angular/core";
|
import {Component, OnInit, ViewChild} from "@angular/core";
|
||||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||||
import {Router} from "@angular/router";
|
|
||||||
import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO";
|
import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO";
|
||||||
import {Utils} from "../../../../common/Utils";
|
import {Utils} from "../../../../common/Utils";
|
||||||
import {UserManagerSettingsService} from "./usermanager.settings.service";
|
import {UserManagerSettingsService} from "./usermanager.settings.service";
|
||||||
import {ModalDirective} from "ngx-bootstrap/modal";
|
import {ModalDirective} from "ngx-bootstrap/modal";
|
||||||
|
import {NavigationService} from "../../model/navigation.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'settings-usermanager',
|
selector: 'settings-usermanager',
|
||||||
@ -18,16 +18,18 @@ export class UserMangerSettingsComponent implements OnInit {
|
|||||||
public userRoles: Array<any> = [];
|
public userRoles: Array<any> = [];
|
||||||
public users: Array<UserDTO> = [];
|
public users: Array<UserDTO> = [];
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService, private _router: Router, private _userSettings: UserManagerSettingsService) {
|
constructor(private _authService: AuthenticationService, private _navigation: NavigationService, private _userSettings: UserManagerSettingsService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (!this._authService.isAuthenticated() || this._authService.user.value.role < UserRoles.Admin) {
|
if (!this._authService.isAuthenticated() ||
|
||||||
this._router.navigate(['login']);
|
this._authService.user.value.role < UserRoles.Admin) {
|
||||||
|
this._navigation.toLogin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.userRoles = Utils
|
this.userRoles = Utils
|
||||||
.enumToArray(UserRoles)
|
.enumToArray(UserRoles)
|
||||||
|
.filter(r => r.key != UserRoles.LimitedGuest)
|
||||||
.filter(r => r.key <= this._authService.user.value.role)
|
.filter(r => r.key <= this._authService.user.value.role)
|
||||||
.sort((a, b) => a.key - b.key);
|
.sort((a, b) => a.key - b.key);
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,57 @@
|
|||||||
body {
|
.container {
|
||||||
background: #eee;
|
}
|
||||||
|
|
||||||
|
.title h1 {
|
||||||
|
font-size: 80px;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title img {
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-top: 40px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 15px;
|
||||||
|
max-width: 350px;
|
||||||
|
width: 100% !important;
|
||||||
|
background-color: #F7F7F7;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||||
|
overflow: hidden;
|
||||||
|
height: 150px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Margin by pixel:*/
|
||||||
|
@media screen and ( min-height: 400px ) {
|
||||||
|
.card {
|
||||||
|
margin-top: calc((100vh - 120px - 150px) / 2 - 60px)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-margin {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group .form-control, .checkbox {
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: #d9534f;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,41 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="col-sm-offset-3 col-sm-6 col-lg-4 col-lg-offset-4">
|
|
||||||
<form class="form-signin" #LoginForm="ngForm">
|
<div class="row title">
|
||||||
<h2 class="form-signin-heading">The link is password protected</h2>
|
<h1><img src="assets/icon.png"/>{{title}}</h1>
|
||||||
<div *ngIf="loginError">
|
|
||||||
{{loginError}}
|
|
||||||
</div>
|
|
||||||
<input type="password" class="form-control" placeholder="Password"
|
|
||||||
[(ngModel)]="loginCredential.password" name="password" required>
|
|
||||||
<br/>
|
|
||||||
<button class="btn btn-lg btn-primary btn-block" [disabled]="!LoginForm.form.valid" (click)="onLogin()">OK
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- /container -->
|
|
||||||
|
<div class="row card">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form name="form" id="form" class="form-horizontal" #LoginForm="ngForm" (submit)="onLogin()">
|
||||||
|
<div class="error-message">
|
||||||
|
{{loginError}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group has-margin">
|
||||||
|
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||||
|
<input id="password"
|
||||||
|
class="form-control"
|
||||||
|
type="password"
|
||||||
|
[(ngModel)]="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="Password"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<!-- Button -->
|
||||||
|
<div class="col-sm-12 controls">
|
||||||
|
<button class="btn btn-primary pull-right"
|
||||||
|
[disabled]="!LoginForm.form.valid"
|
||||||
|
type="submit"
|
||||||
|
name="action">Enter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import {Component, OnInit} from "@angular/core";
|
import {Component, OnInit} from "@angular/core";
|
||||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
|
||||||
import {AuthenticationService} from "../model/network/authentication.service";
|
import {AuthenticationService} from "../model/network/authentication.service";
|
||||||
import {Router} from "@angular/router";
|
|
||||||
import {ErrorCodes} from "../../../common/entities/Error";
|
import {ErrorCodes} from "../../../common/entities/Error";
|
||||||
|
import {Config} from "../../../common/config/public/Config";
|
||||||
|
import {NavigationService} from "../model/navigation.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'share-login',
|
selector: 'share-login',
|
||||||
@ -10,16 +10,17 @@ import {ErrorCodes} from "../../../common/entities/Error";
|
|||||||
styleUrls: ['./share-login.component.css'],
|
styleUrls: ['./share-login.component.css'],
|
||||||
})
|
})
|
||||||
export class ShareLoginComponent implements OnInit {
|
export class ShareLoginComponent implements OnInit {
|
||||||
loginCredential: LoginCredential;
|
password: string;
|
||||||
loginError: any = null;
|
loginError: any = null;
|
||||||
|
title: string;
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService, private _router: Router) {
|
constructor(private _authService: AuthenticationService, private _navigation: NavigationService) {
|
||||||
this.loginCredential = new LoginCredential();
|
this.title = Config.Client.applicationTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this._authService.isAuthenticated()) {
|
if (this._authService.isAuthenticated()) {
|
||||||
this._router.navigate(['gallery', "/"]);
|
this._navigation.toGallery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,11 +28,11 @@ export class ShareLoginComponent implements OnInit {
|
|||||||
this.loginError = null;
|
this.loginError = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this._authService.login(this.loginCredential);
|
await this._authService.shareLogin(this.password);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error && error.code === ErrorCodes.CREDENTIAL_NOT_FOUND) {
|
if (error && error.code === ErrorCodes.CREDENTIAL_NOT_FOUND) {
|
||||||
this.loginError = "Wrong username or password";
|
this.loginError = "Wrong password";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,6 +85,7 @@
|
|||||||
"ng2-slim-loading-bar": "^4.0.0",
|
"ng2-slim-loading-bar": "^4.0.0",
|
||||||
"ng2-toastr": "^4.1.2",
|
"ng2-toastr": "^4.1.2",
|
||||||
"ngx-bootstrap": "^1.7.1",
|
"ngx-bootstrap": "^1.7.1",
|
||||||
|
"ngx-clipboard": "^8.0.3",
|
||||||
"phantomjs-prebuilt": "^2.1.14",
|
"phantomjs-prebuilt": "^2.1.14",
|
||||||
"protractor": "^5.1.2",
|
"protractor": "^5.1.2",
|
||||||
"remap-istanbul": "^0.9.5",
|
"remap-istanbul": "^0.9.5",
|
||||||
|
|||||||
@ -86,7 +86,7 @@ describe('Authentication middleware', () => {
|
|||||||
let req: any = {
|
let req: any = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
role: UserRoles.Guest
|
role: UserRoles.LimitedGuest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -94,7 +94,7 @@ describe('Authentication middleware', () => {
|
|||||||
expect(err).to.be.undefined;
|
expect(err).to.be.undefined;
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
AuthenticationMWs.authorise(UserRoles.Guest)(req, null, next);
|
AuthenticationMWs.authorise(UserRoles.LimitedGuest)(req, null, next);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ describe('Authentication middleware', () => {
|
|||||||
let req: any = {
|
let req: any = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
role: UserRoles.Guest
|
role: UserRoles.LimitedGuest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -230,7 +230,7 @@ describe('Authentication middleware', () => {
|
|||||||
let req: any = {
|
let req: any = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
role: UserRoles.Guest
|
role: UserRoles.LimitedGuest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user