Picsur/frontend/src/app/services/api/sys-pref.service.ts

155 lines
4 KiB
TypeScript
Raw Normal View History

2022-03-19 18:30:47 +00:00
import { Injectable } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import {
2022-06-05 10:20:16 +00:00
GetPreferenceResponse,
MultiplePreferencesResponse,
UpdatePreferenceRequest,
2022-09-06 14:32:16 +00:00
UpdatePreferenceResponse,
2022-04-13 15:49:30 +00:00
} from 'picsur-shared/dist/dto/api/pref.dto';
2022-06-27 13:23:06 +00:00
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
2022-04-13 15:49:30 +00:00
import {
2022-06-05 10:20:16 +00:00
DecodedPref,
2022-09-06 14:32:16 +00:00
PrefValueType,
2022-04-13 15:49:30 +00:00
} from 'picsur-shared/dist/dto/preferences.dto';
import {
AsyncFailable,
Fail,
FT,
HasFailed,
2022-09-06 14:32:16 +00:00
Map,
} from 'picsur-shared/dist/types';
2022-03-19 18:30:47 +00:00
import { BehaviorSubject } from 'rxjs';
import { ErrorService } from 'src/app/util/error-manager/error.service';
2022-04-13 19:14:24 +00:00
import { Throttle } from 'src/app/util/throttle';
2022-03-30 09:58:26 +00:00
import { Logger } from '../logger/logger.service';
2022-03-19 18:30:47 +00:00
import { ApiService } from './api.service';
import { PermissionService } from './permission.service';
@Injectable({
providedIn: 'root',
})
2022-04-13 15:49:30 +00:00
export class SysPrefService {
2022-09-02 15:18:22 +00:00
private readonly logger = new Logger(SysPrefService.name);
2022-03-30 09:58:26 +00:00
2022-03-19 18:30:47 +00:00
private hasPermission = false;
2022-04-13 15:49:30 +00:00
private sysprefObservable = new BehaviorSubject<DecodedPref[]>([]);
2022-03-30 09:40:50 +00:00
2022-03-19 18:30:47 +00:00
public get snapshot() {
return this.sysprefObservable.getValue();
}
public get live() {
2022-03-30 09:40:50 +00:00
return this.sysprefObservable.asObservable();
2022-03-19 18:30:47 +00:00
}
constructor(
2022-06-27 15:37:37 +00:00
private readonly api: ApiService,
private readonly permissionsService: PermissionService,
private readonly errorService: ErrorService,
2022-03-19 18:30:47 +00:00
) {
2022-03-29 18:39:00 +00:00
this.subscribePermissions();
}
2022-04-13 19:14:24 +00:00
private async refresh() {
2022-03-29 18:39:00 +00:00
const result = await this.getPreferences();
if (HasFailed(result)) {
this.errorService.showFailure(result, this.logger);
2022-03-29 18:39:00 +00:00
this.flush();
}
2022-03-19 18:30:47 +00:00
}
2022-04-13 15:49:30 +00:00
public async getPreferences(): AsyncFailable<DecodedPref[]> {
2022-03-19 18:30:47 +00:00
if (!this.hasPermission)
2022-07-04 15:11:42 +00:00
return Fail(
FT.Permission,
'You do not have permission to edit system preferences',
);
2022-03-19 18:30:47 +00:00
const response = await this.api.get(
2022-04-13 15:49:30 +00:00
MultiplePreferencesResponse,
2022-06-05 10:20:16 +00:00
'/api/pref/sys',
2022-03-19 18:30:47 +00:00
);
2022-03-30 10:41:40 +00:00
return Map(response, (pref) => {
2022-06-27 13:23:06 +00:00
this.sysprefObservable.next(pref.results);
return pref.results;
2022-03-30 10:41:40 +00:00
});
2022-03-19 18:30:47 +00:00
}
public async getPreference(
2022-06-05 10:20:16 +00:00
key: string,
2022-04-13 15:49:30 +00:00
): AsyncFailable<GetPreferenceResponse> {
2022-03-19 18:30:47 +00:00
if (!this.hasPermission)
2022-07-04 15:11:42 +00:00
return Fail(
FT.Permission,
'You do not have permission to edit system preferences',
);
2022-03-19 18:30:47 +00:00
const response = await this.api.get(
2022-04-13 15:49:30 +00:00
GetPreferenceResponse,
2022-06-05 10:20:16 +00:00
`/api/pref/sys/${key}`,
2022-03-19 18:30:47 +00:00
);
2022-03-30 09:40:50 +00:00
if (!HasFailed(response)) this.updatePrefArray(response);
2022-03-19 18:30:47 +00:00
return response;
}
public async setPreference(
2022-03-27 20:33:13 +00:00
key: string,
2022-06-05 10:20:16 +00:00
value: PrefValueType,
2022-04-13 15:49:30 +00:00
): AsyncFailable<UpdatePreferenceResponse> {
2022-03-19 18:30:47 +00:00
if (!this.hasPermission)
2022-07-04 15:11:42 +00:00
return Fail(
FT.Permission,
'You do not have permission to edit system preferences',
);
2022-03-19 18:30:47 +00:00
const response = await this.api.post(
2022-04-13 15:49:30 +00:00
UpdatePreferenceRequest,
UpdatePreferenceResponse,
2022-03-19 18:30:47 +00:00
`/api/pref/sys/${key}`,
2022-06-05 10:20:16 +00:00
{ value },
2022-03-19 18:30:47 +00:00
);
2022-03-30 09:40:50 +00:00
if (!HasFailed(response)) this.updatePrefArray(response);
2022-03-19 18:30:47 +00:00
return response;
}
2022-04-13 15:49:30 +00:00
private updatePrefArray(pref: DecodedPref) {
2022-03-19 18:30:47 +00:00
const prefArray = this.snapshot;
// Replace the old pref with the new one
const index = prefArray.findIndex((i) => pref.key === i.key);
if (index === -1) {
const newArray = [...prefArray, pref];
this.sysprefObservable.next(newArray);
} else {
const newArray = [...prefArray];
newArray[index] = pref;
this.sysprefObservable.next(newArray);
}
}
private flush() {
this.sysprefObservable.next([]);
}
2022-03-30 09:40:50 +00:00
// We want to flush on logout, because the syspreferences can contain sensitive information
2022-03-19 18:30:47 +00:00
@AutoUnsubscribe()
2022-03-29 18:39:00 +00:00
private subscribePermissions() {
2022-04-13 19:14:24 +00:00
return this.permissionsService.live
.pipe(Throttle(300))
.subscribe((permissions) => {
const oldHasPermission = this.hasPermission;
this.hasPermission = permissions.includes(Permission.SysPrefAdmin);
2022-04-13 19:14:24 +00:00
if (!this.hasPermission) {
this.flush();
}
if (!oldHasPermission && this.hasPermission) {
this.refresh().catch(this.logger.error);
}
});
2022-03-19 18:30:47 +00:00
}
}