mirror of
https://github.com/CaramelFur/Picsur.git
synced 2025-11-13 15:25:39 +01:00
add permission handling on frontend
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||
import { UserMePermissionsResponse } from 'picsur-shared/dist/dto/api/user.dto';
|
||||
import { Permissions } from 'picsur-shared/dist/dto/permissions';
|
||||
import {
|
||||
Permissions,
|
||||
PermissionsList
|
||||
} from 'picsur-shared/dist/dto/permissions';
|
||||
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ApiService } from './api.service';
|
||||
@@ -15,19 +18,22 @@ export class PermissionService {
|
||||
this.onUser();
|
||||
}
|
||||
|
||||
public get livePermissions() {
|
||||
public get live() {
|
||||
return this.permissionsSubject;
|
||||
}
|
||||
|
||||
public get permissions() {
|
||||
public get snapshot() {
|
||||
return this.permissionsSubject.getValue();
|
||||
}
|
||||
|
||||
private permissionsSubject = new BehaviorSubject<Permissions>([]);
|
||||
// Lets be optimistic for better ux
|
||||
private permissionsSubject = new BehaviorSubject<Permissions>(
|
||||
PermissionsList as Permissions
|
||||
);
|
||||
|
||||
@AutoUnsubscribe()
|
||||
private onUser() {
|
||||
return this.userService.liveUser.subscribe(async (user) => {
|
||||
return this.userService.live.subscribe(async (user) => {
|
||||
const permissions = await this.fetchPermissions();
|
||||
if (HasFailed(permissions)) {
|
||||
this.logger.warn(permissions.getReason());
|
||||
|
||||
@@ -19,11 +19,11 @@ import { KeyService } from './key.service';
|
||||
export class UserService {
|
||||
private readonly logger = console;
|
||||
|
||||
public get liveUser() {
|
||||
public get live() {
|
||||
return this.userSubject;
|
||||
}
|
||||
|
||||
public get user() {
|
||||
public get snapshot() {
|
||||
return this.userSubject.getValue();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
<footer class="container">
|
||||
<p>
|
||||
Made with 🤍 by
|
||||
<a class="link-unstyled" href="https://rubikscraft.nl" target="_blank"
|
||||
>RubiksCraft</a
|
||||
>
|
||||
-
|
||||
<a class="link-unstyled" href="https://github.com/rubikscraft/picsur"
|
||||
>Source Code</a
|
||||
>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
@@ -3,5 +3,5 @@ footer {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
margin-top: 32px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<button *ngIf="!isLoggedIn" mat-stroked-button (click)="doLogin()">
|
||||
<button *ngIf="!isLoggedIn && canLogIn" mat-stroked-button (click)="doLogin()">
|
||||
Login
|
||||
</button>
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||
import { Permissions } from 'picsur-shared/dist/dto/permissions';
|
||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { PermissionService } from 'src/app/api/permission.service';
|
||||
import { UserService } from 'src/app/api/user.service';
|
||||
import { SnackBarType } from 'src/app/models/snack-bar-type';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
@@ -16,6 +18,7 @@ export class HeaderComponent implements OnInit {
|
||||
private readonly logger = console;
|
||||
|
||||
private currentUser: EUser | null = null;
|
||||
private permissions: Permissions = [];
|
||||
|
||||
public get user() {
|
||||
return this.currentUser;
|
||||
@@ -25,24 +28,36 @@ export class HeaderComponent implements OnInit {
|
||||
return this.currentUser !== null;
|
||||
}
|
||||
|
||||
public get canLogIn() {
|
||||
return this.permissions.includes('user-login');
|
||||
}
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private userService: UserService,
|
||||
private permissionService: PermissionService,
|
||||
private utilService: UtilService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscribeUser();
|
||||
this.subscribePermissions();
|
||||
}
|
||||
|
||||
@AutoUnsubscribe()
|
||||
subscribeUser() {
|
||||
return this.userService.liveUser.subscribe((user) => {
|
||||
this.logger.log('user', user);
|
||||
return this.userService.live.subscribe((user) => {
|
||||
this.currentUser = user;
|
||||
});
|
||||
}
|
||||
|
||||
@AutoUnsubscribe()
|
||||
subscribePermissions() {
|
||||
return this.permissionService.live.subscribe((permissions) => {
|
||||
this.permissions = permissions;
|
||||
});
|
||||
}
|
||||
|
||||
doLogin() {
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,19 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12 py-2">
|
||||
<button mat-raised-button color="accent" type="submit">Login</button>
|
||||
<button mat-raised-button color="accent" class="mx-2" type="submit">
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
*ngIf="showRegister"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
class="mx-2"
|
||||
(click)="onRegister()"
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||
import { Permissions } from 'picsur-shared/dist/dto/permissions';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { PermissionService } from 'src/app/api/permission.service';
|
||||
import { UserService } from 'src/app/api/user.service';
|
||||
import { SnackBarType } from 'src/app/models/snack-bar-type';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
@@ -14,11 +17,18 @@ import { LoginControl } from './login.model';
|
||||
export class LoginComponent implements OnInit {
|
||||
private readonly logger = console;
|
||||
|
||||
private permissions: Permissions = [];
|
||||
|
||||
public get showRegister() {
|
||||
return this.permissions.includes('user-register');
|
||||
}
|
||||
|
||||
model = new LoginControl();
|
||||
loginFail = false;
|
||||
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private permissionService: PermissionService,
|
||||
private router: Router,
|
||||
private utilService: UtilService
|
||||
) {}
|
||||
@@ -26,7 +36,17 @@ export class LoginComponent implements OnInit {
|
||||
ngOnInit(): void {
|
||||
if (this.userService.isLoggedIn) {
|
||||
this.router.navigate(['/'], { replaceUrl: true });
|
||||
return;
|
||||
}
|
||||
|
||||
this.onPermissions();
|
||||
}
|
||||
|
||||
@AutoUnsubscribe()
|
||||
onPermissions() {
|
||||
return this.permissionService.live.subscribe((permissions) => {
|
||||
this.permissions = permissions;
|
||||
});
|
||||
}
|
||||
|
||||
async onSubmit() {
|
||||
@@ -45,4 +65,10 @@ export class LoginComponent implements OnInit {
|
||||
this.utilService.showSnackBar('Login successful', SnackBarType.Success);
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
async onRegister() {
|
||||
//prevent default
|
||||
|
||||
console.log('click');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<div class="content-border">
|
||||
<ngx-dropzone (change)="onSelect($event)">
|
||||
<ngx-dropzone *ngIf="hasUploadPermission" (change)="onSelect($event)">
|
||||
<div class="centered">
|
||||
<h1>Upload Image</h1>
|
||||
<p>Drag and drop an image here, or click to select an image</p>
|
||||
</div>
|
||||
</ngx-dropzone>
|
||||
|
||||
<div class="centered" *ngIf="!hasUploadPermission">
|
||||
<h1>Please Log In</h1>
|
||||
<p>You do not yet have permission to upload</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||
import { NgxDropzoneChangeEvent } from 'ngx-dropzone';
|
||||
import { Permissions } from 'picsur-shared/dist/dto/permissions';
|
||||
import { PermissionService } from 'src/app/api/permission.service';
|
||||
import { UtilService } from 'src/app/util/util.service';
|
||||
import { ProcessingViewMetadata } from '../../models/processing-view-metadata';
|
||||
|
||||
@@ -8,8 +11,31 @@ import { ProcessingViewMetadata } from '../../models/processing-view-metadata';
|
||||
templateUrl: './upload.component.html',
|
||||
styleUrls: ['./upload.component.scss'],
|
||||
})
|
||||
export class UploadComponent {
|
||||
constructor(private utilService: UtilService, private router: Router) {}
|
||||
export class UploadComponent implements OnInit {
|
||||
private permissions: Permissions = [];
|
||||
|
||||
// Lets be optimistic here, this makes for a better ux
|
||||
public get hasUploadPermission() {
|
||||
return this.permissions.includes('image-upload');
|
||||
}
|
||||
|
||||
constructor(
|
||||
private utilService: UtilService,
|
||||
private permissionService: PermissionService,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.onPermission();
|
||||
}
|
||||
|
||||
@AutoUnsubscribe()
|
||||
onPermission() {
|
||||
return this.permissionService.live.subscribe((permissions) => {
|
||||
this.permissions = permissions;
|
||||
});
|
||||
}
|
||||
|
||||
onSelect(event: NgxDropzoneChangeEvent) {
|
||||
if (event.addedFiles.length > 1) {
|
||||
this.utilService.showSnackBar(
|
||||
|
||||
@@ -17,3 +17,28 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.link-unstyled {
|
||||
&,
|
||||
&:visited,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus,
|
||||
&:active:hover {
|
||||
font-style: inherit;
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
font-size: inherit;
|
||||
text-decoration: none;
|
||||
font-variant: inherit;
|
||||
font-weight: bold;
|
||||
line-height: inherit;
|
||||
font-family: inherit;
|
||||
border-radius: inherit;
|
||||
border: inherit;
|
||||
outline: inherit;
|
||||
box-shadow: inherit;
|
||||
padding: inherit;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user