Change some typescript compilation options and fix eslint
This commit is contained in:
parent
3b6244461e
commit
b8db72bac4
|
@ -1,3 +1,22 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
|
||||||
|
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||||
|
extends: [
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
jest: true,
|
||||||
|
},
|
||||||
|
ignorePatterns: ['.eslintrc.cjs', 'dist', '*.exclude.*'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
|
},
|
||||||
root: true,
|
root: true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,27 +1,9 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
project: './tsconfig.json',
|
project: './tsconfig.json',
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
plugins: ['@typescript-eslint/eslint-plugin', 'require-extensions'],
|
extends: ['../.eslintrc.cjs'],
|
||||||
extends: [
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
'plugin:require-extensions/recommended',
|
|
||||||
],
|
|
||||||
root: false,
|
root: false,
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
jest: true,
|
|
||||||
},
|
|
||||||
ignorePatterns: ['.eslintrc.cjs'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
"migrate": "PICSUR_PRODUCTION=\"true\" yarn typeorm migration:generate -d ./src/datasource.ts",
|
"migrate": "PICSUR_PRODUCTION=\"true\" yarn typeorm migration:generate -d ./src/datasource.ts",
|
||||||
"format": "prettier --write \"src/**/*.ts\"",
|
"format": "prettier --write \"src/**/*.ts\"",
|
||||||
"clean": "rimraf dist",
|
"clean": "rimraf dist",
|
||||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
|
||||||
"purge": "rm -rf dist && rm -rf node_modules"
|
"purge": "rm -rf dist && rm -rf node_modules"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -40,10 +39,9 @@
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"bmp-img": "^1.2.1",
|
"bmp-img": "^1.2.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"eslint-plugin-require-extensions": "^0.1.3",
|
|
||||||
"file-type": "^18.5.0",
|
"file-type": "^18.5.0",
|
||||||
"is-docker": "^3.0.0",
|
"is-docker": "^3.0.0",
|
||||||
"ms": "^2.1.3",
|
"ms": "3.0.0-canary.1",
|
||||||
"node-fetch": "^3.3.1",
|
"node-fetch": "^3.3.1",
|
||||||
"p-timeout": "^6.1.1",
|
"p-timeout": "^6.1.1",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
|
@ -77,11 +75,6 @@
|
||||||
"@types/passport-strategy": "^0.2.35",
|
"@types/passport-strategy": "^0.2.35",
|
||||||
"@types/sharp": "^0.32.0",
|
"@types/sharp": "^0.32.0",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
|
||||||
"@typescript-eslint/parser": "^5.59.9",
|
|
||||||
"eslint": "^8.42.0",
|
|
||||||
"eslint-config-prettier": "^8.8.0",
|
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-loader": "^9.4.3",
|
"ts-loader": "^9.4.3",
|
||||||
|
|
|
@ -30,7 +30,7 @@ const imageCorsConfig = cors({
|
||||||
const imageCorsOverride = (
|
const imageCorsOverride = (
|
||||||
req: IncomingMessage,
|
req: IncomingMessage,
|
||||||
res: ServerResponse,
|
res: ServerResponse,
|
||||||
next: Function,
|
next: () => void,
|
||||||
) => {
|
) => {
|
||||||
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
|
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
||||||
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
||||||
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
||||||
import { In, LessThan, Repository } from 'typeorm';
|
import { In, LessThan, Repository } from 'typeorm';
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { LessThan, Repository } from 'typeorm';
|
import { LessThan, Repository } from 'typeorm';
|
||||||
import { EImageDerivativeBackend } from '../../database/entities/images/image-derivative.entity';
|
import { EImageDerivativeBackend } from '../../database/entities/images/image-derivative.entity';
|
||||||
import { EImageFileBackend } from '../../database/entities/images/image-file.entity';
|
import { EImageFileBackend } from '../../database/entities/images/image-file.entity';
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
Failable,
|
Failable,
|
||||||
FT,
|
FT,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types/failable';
|
||||||
|
|
||||||
type Enum = Record<string, string>;
|
type Enum = Record<string, string>;
|
||||||
type EnumValue<E> = E[keyof E];
|
type EnumValue<E> = E[keyof E];
|
||||||
|
|
|
@ -11,7 +11,12 @@ import {
|
||||||
SysPreferenceValidators,
|
SysPreferenceValidators,
|
||||||
SysPreferenceValueTypes,
|
SysPreferenceValueTypes,
|
||||||
} from 'picsur-shared/dist/dto/sys-preferences.enum';
|
} from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
ESysPreferenceBackend,
|
ESysPreferenceBackend,
|
||||||
|
@ -37,7 +42,7 @@ export class SysPreferenceDbService {
|
||||||
value: PrefValueType,
|
value: PrefValueType,
|
||||||
): AsyncFailable<DecodedSysPref> {
|
): AsyncFailable<DecodedSysPref> {
|
||||||
// Validate
|
// Validate
|
||||||
let sysPreference = await this.encodeSysPref(key, value);
|
const sysPreference = await this.encodeSysPref(key, value);
|
||||||
if (HasFailed(sysPreference)) return sysPreference;
|
if (HasFailed(sysPreference)) return sysPreference;
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
|
@ -60,7 +65,7 @@ export class SysPreferenceDbService {
|
||||||
|
|
||||||
public async getPreference(key: string): AsyncFailable<DecodedSysPref> {
|
public async getPreference(key: string): AsyncFailable<DecodedSysPref> {
|
||||||
// Validate
|
// Validate
|
||||||
let validatedKey = this.prefCommon.validatePrefKey(key, SysPreference);
|
const validatedKey = this.prefCommon.validatePrefKey(key, SysPreference);
|
||||||
if (HasFailed(validatedKey)) return validatedKey;
|
if (HasFailed(validatedKey)) return validatedKey;
|
||||||
|
|
||||||
// See the comment in 'mutex-fallback.ts' for why we are using a mutex here
|
// See the comment in 'mutex-fallback.ts' for why we are using a mutex here
|
||||||
|
@ -112,7 +117,7 @@ export class SysPreferenceDbService {
|
||||||
key: string,
|
key: string,
|
||||||
type: PrefValueTypeStrings,
|
type: PrefValueTypeStrings,
|
||||||
): AsyncFailable<PrefValueType> {
|
): AsyncFailable<PrefValueType> {
|
||||||
let pref = await this.getPreference(key);
|
const pref = await this.getPreference(key);
|
||||||
if (HasFailed(pref)) return pref;
|
if (HasFailed(pref)) return pref;
|
||||||
if (pref.type !== type)
|
if (pref.type !== type)
|
||||||
return Fail(FT.UsrValidation, 'Invalid preference type');
|
return Fail(FT.UsrValidation, 'Invalid preference type');
|
||||||
|
@ -122,7 +127,7 @@ export class SysPreferenceDbService {
|
||||||
|
|
||||||
public async getAllPreferences(): AsyncFailable<DecodedSysPref[]> {
|
public async getAllPreferences(): AsyncFailable<DecodedSysPref[]> {
|
||||||
// TODO: We are fetching each value invidually, we should fetch all at once
|
// TODO: We are fetching each value invidually, we should fetch all at once
|
||||||
let internalSysPrefs = await Promise.all(
|
const internalSysPrefs = await Promise.all(
|
||||||
SysPreferenceList.map((key) => this.getPreference(key)),
|
SysPreferenceList.map((key) => this.getPreference(key)),
|
||||||
);
|
);
|
||||||
if (internalSysPrefs.some((pref) => HasFailed(pref))) {
|
if (internalSysPrefs.some((pref) => HasFailed(pref))) {
|
||||||
|
@ -158,7 +163,7 @@ export class SysPreferenceDbService {
|
||||||
return Fail(FT.UsrValidation, undefined, valueValidated.error);
|
return Fail(FT.UsrValidation, undefined, valueValidated.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let verifySysPreference = new ESysPreferenceBackend();
|
const verifySysPreference = new ESysPreferenceBackend();
|
||||||
verifySysPreference.key = validated.key;
|
verifySysPreference.key = validated.key;
|
||||||
verifySysPreference.value = validated.value;
|
verifySysPreference.value = validated.value;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,12 @@ import {
|
||||||
UsrPreferenceValidators,
|
UsrPreferenceValidators,
|
||||||
UsrPreferenceValueTypes,
|
UsrPreferenceValueTypes,
|
||||||
} from 'picsur-shared/dist/dto/usr-preferences.enum';
|
} from 'picsur-shared/dist/dto/usr-preferences.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
EUsrPreferenceBackend,
|
EUsrPreferenceBackend,
|
||||||
|
@ -38,7 +43,7 @@ export class UsrPreferenceDbService {
|
||||||
value: PrefValueType,
|
value: PrefValueType,
|
||||||
): AsyncFailable<DecodedUsrPref> {
|
): AsyncFailable<DecodedUsrPref> {
|
||||||
// Validate
|
// Validate
|
||||||
let usrPreference = await this.encodeUsrPref(userid, key, value);
|
const usrPreference = await this.encodeUsrPref(userid, key, value);
|
||||||
if (HasFailed(usrPreference)) return usrPreference;
|
if (HasFailed(usrPreference)) return usrPreference;
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
|
@ -66,7 +71,7 @@ export class UsrPreferenceDbService {
|
||||||
key: string,
|
key: string,
|
||||||
): AsyncFailable<DecodedUsrPref> {
|
): AsyncFailable<DecodedUsrPref> {
|
||||||
// Validate
|
// Validate
|
||||||
let validatedKey = this.prefCommon.validatePrefKey(key, UsrPreference);
|
const validatedKey = this.prefCommon.validatePrefKey(key, UsrPreference);
|
||||||
if (HasFailed(validatedKey)) return validatedKey;
|
if (HasFailed(validatedKey)) return validatedKey;
|
||||||
|
|
||||||
// See the comment in 'mutex-fallback.ts' for why we are using a mutex here
|
// See the comment in 'mutex-fallback.ts' for why we are using a mutex here
|
||||||
|
@ -145,7 +150,7 @@ export class UsrPreferenceDbService {
|
||||||
key: string,
|
key: string,
|
||||||
type: PrefValueTypeStrings,
|
type: PrefValueTypeStrings,
|
||||||
): AsyncFailable<PrefValueType> {
|
): AsyncFailable<PrefValueType> {
|
||||||
let pref = await this.getPreference(userid, key);
|
const pref = await this.getPreference(userid, key);
|
||||||
if (HasFailed(pref)) return pref;
|
if (HasFailed(pref)) return pref;
|
||||||
if (pref.type !== type)
|
if (pref.type !== type)
|
||||||
return Fail(FT.UsrValidation, 'Invalid preference type');
|
return Fail(FT.UsrValidation, 'Invalid preference type');
|
||||||
|
@ -157,7 +162,7 @@ export class UsrPreferenceDbService {
|
||||||
userid: string,
|
userid: string,
|
||||||
): AsyncFailable<DecodedUsrPref[]> {
|
): AsyncFailable<DecodedUsrPref[]> {
|
||||||
// TODO: We are fetching each value invidually, we should fetch all at once
|
// TODO: We are fetching each value invidually, we should fetch all at once
|
||||||
let internalSysPrefs = await Promise.all(
|
const internalSysPrefs = await Promise.all(
|
||||||
UsrPreferenceList.map((key) => this.getPreference(userid, key)),
|
UsrPreferenceList.map((key) => this.getPreference(userid, key)),
|
||||||
);
|
);
|
||||||
if (internalSysPrefs.some((pref) => HasFailed(pref))) {
|
if (internalSysPrefs.some((pref) => HasFailed(pref))) {
|
||||||
|
@ -199,7 +204,7 @@ export class UsrPreferenceDbService {
|
||||||
return Fail(FT.UsrValidation, undefined, valueValidated.error);
|
return Fail(FT.UsrValidation, undefined, valueValidated.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let verifySysPreference = new EUsrPreferenceBackend();
|
const verifySysPreference = new EUsrPreferenceBackend();
|
||||||
verifySysPreference.key = validated.key;
|
verifySysPreference.key = validated.key;
|
||||||
verifySysPreference.value = validated.value;
|
verifySysPreference.value = validated.value;
|
||||||
verifySysPreference.user_id = userid;
|
verifySysPreference.user_id = userid;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { EarlyConfigModule } from '../../config/early/early-config.module';
|
import { EarlyConfigModule } from '../../config/early/early-config.module';
|
||||||
import { HostConfigService } from '../../config/early/host.config.service';
|
import { HostConfigService } from '../../config/early/host.config.service';
|
||||||
import { ERoleBackend } from '../../database/entities/users/role.entity';
|
import { ERoleBackend } from '../../database/entities/users/role.entity';
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
FT,
|
FT,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
HasSuccess,
|
HasSuccess,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
||||||
import { In, Repository } from 'typeorm';
|
import { In, Repository } from 'typeorm';
|
||||||
import { ERoleBackend } from '../../database/entities/users/role.entity';
|
import { ERoleBackend } from '../../database/entities/users/role.entity';
|
||||||
|
@ -33,7 +33,7 @@ export class RoleDbService {
|
||||||
if (await this.exists(name))
|
if (await this.exists(name))
|
||||||
return Fail(FT.Conflict, 'Role already exists');
|
return Fail(FT.Conflict, 'Role already exists');
|
||||||
|
|
||||||
let role = new ERoleBackend();
|
const role = new ERoleBackend();
|
||||||
role.name = name;
|
role.name = name;
|
||||||
role.permissions = permissions;
|
role.permissions = permissions;
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ export class RoleDbService {
|
||||||
role: string | ERoleBackend,
|
role: string | ERoleBackend,
|
||||||
permissions: Permissions,
|
permissions: Permissions,
|
||||||
// Extra bypass for internal use
|
// Extra bypass for internal use
|
||||||
allowImmutable: boolean = false,
|
allowImmutable = false,
|
||||||
): AsyncFailable<ERoleBackend> {
|
): AsyncFailable<ERoleBackend> {
|
||||||
const roleToModify = await this.resolve(role);
|
const roleToModify = await this.resolve(role);
|
||||||
if (HasFailed(roleToModify)) return roleToModify;
|
if (HasFailed(roleToModify)) return roleToModify;
|
||||||
|
@ -166,7 +166,7 @@ export class RoleDbService {
|
||||||
return HasSuccess(await this.findOne(name));
|
return HasSuccess(await this.findOne(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async nukeSystemRoles(IAmSure: boolean = false): AsyncFailable<true> {
|
public async nukeSystemRoles(IAmSure = false): AsyncFailable<true> {
|
||||||
if (!IAmSure)
|
if (!IAmSure)
|
||||||
return Fail(
|
return Fail(
|
||||||
FT.SysValidation,
|
FT.SysValidation,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { ESystemStateBackend } from '../../database/entities/system/system-state.entity';
|
import { ESystemStateBackend } from '../../database/entities/system/system-state.entity';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
||||||
import { AuthConfigService } from '../../config/early/auth.config.service';
|
import { AuthConfigService } from '../../config/early/auth.config.service';
|
||||||
import { EarlyConfigModule } from '../../config/early/early-config.module';
|
import { EarlyConfigModule } from '../../config/early/early-config.module';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
FT,
|
FT,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
HasSuccess,
|
HasSuccess,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
||||||
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
@ -53,7 +53,7 @@ export class UserDbService {
|
||||||
const strength = await this.getBCryptStrength();
|
const strength = await this.getBCryptStrength();
|
||||||
const hashedPassword = await bcrypt.hash(password, strength);
|
const hashedPassword = await bcrypt.hash(password, strength);
|
||||||
|
|
||||||
let user = new EUserBackend();
|
const user = new EUserBackend();
|
||||||
user.username = username;
|
user.username = username;
|
||||||
user.hashed_password = hashedPassword;
|
user.hashed_password = hashedPassword;
|
||||||
if (byPassRoleCheck) {
|
if (byPassRoleCheck) {
|
||||||
|
@ -208,7 +208,7 @@ export class UserDbService {
|
||||||
username: string,
|
username: string,
|
||||||
// Also fetch fields that aren't normally sent to the client
|
// Also fetch fields that aren't normally sent to the client
|
||||||
// (e.g. hashed password)
|
// (e.g. hashed password)
|
||||||
getPrivate: boolean = false,
|
getPrivate = false,
|
||||||
): AsyncFailable<EUserBackend> {
|
): AsyncFailable<EUserBackend> {
|
||||||
try {
|
try {
|
||||||
const found = await this.usersRepository.findOne({
|
const found = await this.usersRepository.findOne({
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
|
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
|
||||||
import { ParseInt, ParseString } from 'picsur-shared/dist/util/parse-simple';
|
import { ParseInt, ParseString } from 'picsur-shared/dist/util/parse-simple';
|
||||||
import { EntityList } from '../../database/entities';
|
import { EntityList } from '../../database/entities/index';
|
||||||
import { MigrationList } from '../../database/migrations';
|
import { MigrationList } from '../../database/migrations/index';
|
||||||
import { DefaultName, EnvPrefix } from '../config.static';
|
import { DefaultName, EnvPrefix } from '../config.static';
|
||||||
import { HostConfigService } from './host.config.service';
|
import { HostConfigService } from './host.config.service';
|
||||||
|
|
||||||
|
@ -48,10 +48,10 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory {
|
||||||
return varOptions;
|
return varOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createTypeOrmOptions(connectionName?: string) {
|
public createTypeOrmOptions() {
|
||||||
const varOptions = this.getTypeOrmServerOptions();
|
const varOptions = this.getTypeOrmServerOptions();
|
||||||
return {
|
return {
|
||||||
type: 'postgres' as 'postgres',
|
type: 'postgres' as const,
|
||||||
synchronize: !this.hostService.isProduction(),
|
synchronize: !this.hostService.isProduction(),
|
||||||
|
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { FactoryProvider, Injectable, Logger } from '@nestjs/common';
|
import { FactoryProvider, Injectable, Logger } from '@nestjs/common';
|
||||||
import { JwtModuleOptions, JwtOptionsFactory } from '@nestjs/jwt';
|
import { JwtModuleOptions, JwtOptionsFactory } from '@nestjs/jwt';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { URLRegex, UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
import { URLRegex, UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||||
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
||||||
import { ReportInterval, ReportUrl } from '../config.static';
|
import { ReportInterval, ReportUrl } from '../config.static';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { IsEntityID } from 'picsur-shared/dist/validators/entity-id.validator';
|
import { IsEntityID } from 'picsur-shared/dist/validators/entity-id.validator';
|
||||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
import z from 'zod';
|
import * as z from 'zod';
|
||||||
|
|
||||||
export const ESysPreferenceSchema = z.object({
|
export const ESysPreferenceSchema = z.object({
|
||||||
id: IsEntityID().optional(),
|
id: IsEntityID().optional(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Unique,
|
Unique,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import z from 'zod';
|
import * as z from 'zod';
|
||||||
import { EUserBackend } from '../users/user.entity';
|
import { EUserBackend } from '../users/user.entity';
|
||||||
|
|
||||||
export const EUsrPreferenceSchema = z.object({
|
export const EUsrPreferenceSchema = z.object({
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { MigrationInterface } from 'typeorm';
|
||||||
import { V030A1661692206479 } from './1661692206479-V_0_3_0_a';
|
import { V030A1661692206479 } from './1661692206479-V_0_3_0_a';
|
||||||
import { V032A1662029904716 } from './1662029904716-V_0_3_2_a';
|
import { V032A1662029904716 } from './1662029904716-V_0_3_2_a';
|
||||||
import { V040A1662314197741 } from './1662314197741-V_0_4_0_a';
|
import { V040A1662314197741 } from './1662314197741-V_0_4_0_a';
|
||||||
|
@ -5,8 +6,9 @@ import { V040B1662485374471 } from './1662485374471-V_0_4_0_b';
|
||||||
import { V040C1662535484200 } from './1662535484200-V_0_4_0_c';
|
import { V040C1662535484200 } from './1662535484200-V_0_4_0_c';
|
||||||
import { V040D1662728275448 } from './1662728275448-V_0_4_0_d';
|
import { V040D1662728275448 } from './1662728275448-V_0_4_0_d';
|
||||||
import { V050A1672154027079 } from './1672154027079-V_0_5_0_a';
|
import { V050A1672154027079 } from './1672154027079-V_0_5_0_a';
|
||||||
|
import { Newable } from 'picsur-shared/dist/types/newable.js';
|
||||||
|
|
||||||
export const MigrationList: Function[] = [
|
export const MigrationList: Newable<MigrationInterface>[] = [
|
||||||
V030A1661692206479,
|
V030A1661692206479,
|
||||||
V032A1662029904716,
|
V032A1662029904716,
|
||||||
V040A1662314197741,
|
V040A1662314197741,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
|
import { Injectable, PipeTransform } from '@nestjs/common';
|
||||||
import { Ext2FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
import { Ext2FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import { FT, Fail, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||||
import { ImageFullId } from '../../models/constants/image-full-id.const';
|
import { ImageFullId } from '../../models/constants/image-full-id.const';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImageFullIdPipe implements PipeTransform<string, ImageFullId> {
|
export class ImageFullIdPipe implements PipeTransform<string, ImageFullId> {
|
||||||
transform(value: string, metadata: ArgumentMetadata): ImageFullId {
|
transform(value: string): ImageFullId {
|
||||||
const split = value.split('.');
|
const split = value.split('.');
|
||||||
if (split.length === 2) {
|
if (split.length === 2) {
|
||||||
const [id, ext] = split;
|
const [id, ext] = split;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
|
import { Injectable, PipeTransform } from '@nestjs/common';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { FT, Fail } from 'picsur-shared/dist/types/failable';
|
||||||
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImageIdPipe implements PipeTransform<string, string> {
|
export class ImageIdPipe implements PipeTransform<string, string> {
|
||||||
transform(value: string, metadata: ArgumentMetadata): string {
|
transform(value: string): string {
|
||||||
if (UUIDRegex.test(value)) return value;
|
if (UUIDRegex.test(value)) return value;
|
||||||
throw Fail(FT.UsrValidation, 'Invalid image id');
|
throw Fail(FT.UsrValidation, 'Invalid image id');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Multipart, MultipartFile } from '@fastify/multipart';
|
import { Multipart, MultipartFile } from '@fastify/multipart';
|
||||||
import { Injectable, Logger, PipeTransform, Scope } from '@nestjs/common';
|
import { Injectable, Logger, PipeTransform, Scope } from '@nestjs/common';
|
||||||
import { FastifyRequest } from 'fastify';
|
import { FastifyRequest } from 'fastify';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
||||||
|
|
||||||
@Injectable({ scope: Scope.REQUEST })
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
|
@ -12,7 +12,7 @@ export class PostFilePipe implements PipeTransform {
|
||||||
private readonly multipartConfigService: MultipartConfigService,
|
private readonly multipartConfigService: MultipartConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async transform({ request, data }: { data: any; request: FastifyRequest }) {
|
async transform({ request }: { request: FastifyRequest }) {
|
||||||
if (!request.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid file');
|
if (!request.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||||
|
|
||||||
// Only one file is allowed
|
// Only one file is allowed
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import { MultipartFile } from '@fastify/multipart';
|
import { MultipartFile } from '@fastify/multipart';
|
||||||
import {
|
import { Injectable, Logger, PipeTransform, Scope } from '@nestjs/common';
|
||||||
ArgumentMetadata,
|
|
||||||
Injectable,
|
|
||||||
Logger,
|
|
||||||
PipeTransform,
|
|
||||||
Scope,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { FastifyRequest } from 'fastify';
|
import { FastifyRequest } from 'fastify';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { FT, Fail } from 'picsur-shared/dist/types/failable';
|
||||||
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
||||||
|
|
||||||
export type FileIterator = AsyncIterableIterator<MultipartFile>;
|
export type FileIterator = AsyncIterableIterator<MultipartFile>;
|
||||||
|
@ -20,10 +14,7 @@ export class MultiPartPipe implements PipeTransform {
|
||||||
private readonly multipartConfigService: MultipartConfigService,
|
private readonly multipartConfigService: MultipartConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async transform<T extends Object>(
|
async transform({ request, data }: { data: any; request: FastifyRequest }) {
|
||||||
{ request, data }: { data: any; request: FastifyRequest },
|
|
||||||
metadata: ArgumentMetadata,
|
|
||||||
) {
|
|
||||||
const filesLimit = typeof data === 'number' ? data : undefined;
|
const filesLimit = typeof data === 'number' ? data : undefined;
|
||||||
|
|
||||||
if (!request.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid files');
|
if (!request.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid files');
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
SetMetadata,
|
SetMetadata,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { CombineFCDecorators } from 'picsur-shared/dist/util/decorator';
|
import { CombineFCDecorators } from 'picsur-shared/dist/util/decorator';
|
||||||
import { LocalAuthGuard } from '../managers/auth/guards/local-auth.guard';
|
import { LocalAuthGuard } from '../managers/auth/guards/local-auth.guard';
|
||||||
import { Permission, Permissions } from '../models/constants/permissions.const';
|
import { Permission, Permissions } from '../models/constants/permissions.const';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import AuthFastifyRequest from '../models/interfaces/authrequest.dto';
|
import AuthFastifyRequest from '../models/interfaces/authrequest.dto';
|
||||||
|
|
||||||
export const ReqUser = createParamDecorator(
|
export const ReqUser = createParamDecorator(
|
||||||
|
|
|
@ -6,12 +6,12 @@ import { Newable } from 'picsur-shared/dist/types/newable';
|
||||||
type ReturnsMethodDecorator<ReturnType> = <
|
type ReturnsMethodDecorator<ReturnType> = <
|
||||||
T extends (...args: any) => ReturnType | Promise<ReturnType>,
|
T extends (...args: any) => ReturnType | Promise<ReturnType>,
|
||||||
>(
|
>(
|
||||||
target: Object,
|
target: object,
|
||||||
propertyKey: string | symbol,
|
propertyKey: string | symbol,
|
||||||
descriptor: TypedPropertyDescriptor<T>,
|
descriptor: TypedPropertyDescriptor<T>,
|
||||||
) => TypedPropertyDescriptor<T> | void;
|
) => TypedPropertyDescriptor<T> | void;
|
||||||
|
|
||||||
export function Returns<N extends Object>(
|
export function Returns<N extends object>(
|
||||||
newable: Newable<N>,
|
newable: Newable<N>,
|
||||||
): ReturnsMethodDecorator<N> {
|
): ReturnsMethodDecorator<N> {
|
||||||
return SetMetadata('returns', newable);
|
return SetMetadata('returns', newable);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { FastifyReply } from 'fastify';
|
import { FastifyReply } from 'fastify';
|
||||||
import { ApiAnySuccessResponse } from 'picsur-shared/dist/dto/api/api.dto';
|
import { ApiAnySuccessResponse } from 'picsur-shared/dist/dto/api/api.dto';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
||||||
import { map, Observable } from 'rxjs';
|
import { map, Observable } from 'rxjs';
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ export interface ZodValidationInterceptorOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SuccessInterceptor<T> implements NestInterceptor {
|
export class SuccessInterceptor implements NestInterceptor {
|
||||||
private readonly logger = new Logger();
|
private readonly logger = new Logger();
|
||||||
|
|
||||||
// TODO: make work
|
// TODO: make work
|
||||||
|
@ -82,7 +82,7 @@ export class SuccessInterceptor<T> implements NestInterceptor {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let schema = schemaStatic.zodSchema;
|
const schema = schemaStatic.zodSchema;
|
||||||
|
|
||||||
const parseResult = schema.safeParse(data);
|
const parseResult = schema.safeParse(data);
|
||||||
if (!parseResult.success) {
|
if (!parseResult.success) {
|
||||||
|
@ -105,7 +105,7 @@ export class SuccessInterceptor<T> implements NestInterceptor {
|
||||||
const response = context.switchToHttp().getResponse<FastifyReply>();
|
const response = context.switchToHttp().getResponse<FastifyReply>();
|
||||||
|
|
||||||
const newResponse: ApiAnySuccessResponse = {
|
const newResponse: ApiAnySuccessResponse = {
|
||||||
success: true as true, // really typescript
|
success: true as const, // really typescript
|
||||||
statusCode: response.statusCode,
|
statusCode: response.statusCode,
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
timeMs: Math.round(response.getResponseTime()),
|
timeMs: Math.round(response.getResponseTime()),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { ThrottlerGuard } from '@nestjs/throttler';
|
import { ThrottlerGuard } from '@nestjs/throttler';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { FT, Fail } from 'picsur-shared/dist/types/failable';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PicsurThrottlerGuard extends ThrottlerGuard {
|
export class PicsurThrottlerGuard extends ThrottlerGuard {
|
||||||
protected override throwThrottlingException(context: ExecutionContext): void {
|
protected override throwThrottlingException(): void {
|
||||||
throw Fail(FT.RateLimit);
|
throw Fail(FT.RateLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
Optional,
|
Optional,
|
||||||
PipeTransform,
|
PipeTransform,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
import { Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
||||||
|
|
||||||
export interface ZodValidationPipeOptions {
|
export interface ZodValidationPipeOptions {
|
||||||
|
@ -30,7 +30,7 @@ export class ZodValidationPipe implements PipeTransform {
|
||||||
public transform(value: unknown, metadata: ArgumentMetadata): unknown {
|
public transform(value: unknown, metadata: ArgumentMetadata): unknown {
|
||||||
if (!this.validateCustom && metadata.type === 'custom') return value;
|
if (!this.validateCustom && metadata.type === 'custom') return value;
|
||||||
|
|
||||||
let zodSchema = (metadata?.metatype as ZodDtoStatic)?.zodSchema;
|
const zodSchema = (metadata?.metatype as ZodDtoStatic)?.zodSchema;
|
||||||
|
|
||||||
if (zodSchema) {
|
if (zodSchema) {
|
||||||
const parseResult = zodSchema.safeParse(value);
|
const parseResult = zodSchema.safeParse(value);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { JwtData, JwtDataSchema } from 'picsur-shared/dist/dto/jwt.dto';
|
import { JwtData, JwtDataSchema } from 'picsur-shared/dist/dto/jwt.dto';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthManagerService {
|
export class AuthManagerService {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
|
import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
|
||||||
import { EUser, EUserSchema } from 'picsur-shared/dist/entities/user.entity';
|
import { EUser, EUserSchema } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { IsApiKey } from 'picsur-shared/dist/validators/api-key.validator';
|
import { IsApiKey } from 'picsur-shared/dist/validators/api-key.validator';
|
||||||
import { ApiKeyDbService } from '../../../collections/apikey-db/apikey-db.service';
|
import { ApiKeyDbService } from '../../../collections/apikey-db/apikey-db.service';
|
||||||
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
||||||
|
@ -23,7 +23,7 @@ export class ApiKeyStrategy extends PassportStrategy(
|
||||||
false,
|
false,
|
||||||
(
|
(
|
||||||
apikey: string,
|
apikey: string,
|
||||||
verified: (err: Error | null, user?: Object, info?: Object) => void,
|
verified: (err: Error | null, user?: object, info?: object) => void,
|
||||||
) => {
|
) => {
|
||||||
this.validate(apikey)
|
this.validate(apikey)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
|
|
|
@ -8,11 +8,12 @@ import { ReqType } from './reqtype';
|
||||||
|
|
||||||
class GuestPassportStrategy extends Strategy {
|
class GuestPassportStrategy extends Strategy {
|
||||||
// Will be overridden by the nest implementation
|
// Will be overridden by the nest implementation
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
async validate(req: ReqType): Promise<any> {
|
async validate(req: ReqType): Promise<any> {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async authenticate(req: ReqType, options?: any) {
|
override async authenticate(req: ReqType) {
|
||||||
const user = await this.validate(req);
|
const user = await this.validate(req);
|
||||||
this.success(user);
|
this.success(user);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +29,7 @@ export class GuestStrategy extends PassportStrategy(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the guest user created by the guestservice
|
// Return the guest user created by the guestservice
|
||||||
override async validate(payload: any): Promise<EUser> {
|
override async validate(): Promise<EUser> {
|
||||||
return EUserBackend2EUser(await this.guestService.getGuestUser());
|
return EUserBackend2EUser(await this.guestService.getGuestUser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { ExtractJwt, Strategy as JwtPassportStrategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy as JwtPassportStrategy } from 'passport-jwt';
|
||||||
import { JwtDataSchema } from 'picsur-shared/dist/dto/jwt.dto';
|
import { JwtDataSchema } from 'picsur-shared/dist/dto/jwt.dto';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,10 @@ import { Injectable } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { Strategy } from 'passport-local';
|
import { Strategy } from 'passport-local';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { AsyncFailable, ThrowIfFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
ThrowIfFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
FT,
|
FT,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
ThrowIfFailed,
|
ThrowIfFailed,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import { Permissions } from '../../../models/constants/permissions.const';
|
import { Permissions } from '../../../models/constants/permissions.const';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../collections/user-db/user-db.service';
|
||||||
import { EUserBackend } from '../../database/entities/users/user.entity';
|
import { EUserBackend } from '../../database/entities/users/user.entity';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,12 @@ import {
|
||||||
SupportedFileTypeCategory,
|
SupportedFileTypeCategory,
|
||||||
} from 'picsur-shared/dist/dto/mimes.dto';
|
} from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { SharpOptions } from 'sharp';
|
import { SharpOptions } from 'sharp';
|
||||||
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
import { SysPreferenceDbService } from '../../collections/preference-db/sys-preference-db.service';
|
||||||
import { SharpWrapper } from '../../workers/sharp.wrapper';
|
import { SharpWrapper } from '../../workers/sharp.wrapper';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
||||||
import { Interval } from '@nestjs/schedule';
|
import { Interval } from '@nestjs/schedule';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { ImageDBModule } from '../../collections/image-db/image-db.module';
|
import { ImageDBModule } from '../../collections/image-db/image-db.module';
|
||||||
import { ImageDBService } from '../../collections/image-db/image-db.service';
|
import { ImageDBService } from '../../collections/image-db/image-db.service';
|
||||||
import { ImageFileDBService } from '../../collections/image-db/image-file-db.service';
|
import { ImageFileDBService } from '../../collections/image-db/image-file-db.service';
|
||||||
|
|
|
@ -5,7 +5,12 @@ import {
|
||||||
SupportedFileTypeCategory,
|
SupportedFileTypeCategory,
|
||||||
} from 'picsur-shared/dist/dto/mimes.dto';
|
} from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
|
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { ParseFileType } from 'picsur-shared/dist/util/parse-mime';
|
import { ParseFileType } from 'picsur-shared/dist/util/parse-mime';
|
||||||
import { ImageConverterService } from './image-converter.service';
|
import { ImageConverterService } from './image-converter.service';
|
||||||
import { ImageResult } from './imageresult';
|
import { ImageResult } from './imageresult';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import Crypto from 'crypto';
|
import { createHash } from 'crypto';
|
||||||
import { fileTypeFromBuffer, FileTypeResult } from 'file-type';
|
import { fileTypeFromBuffer, FileTypeResult } from 'file-type';
|
||||||
import { ImageRequestParams } from 'picsur-shared/dist/dto/api/image.dto';
|
import { ImageRequestParams } from 'picsur-shared/dist/dto/api/image.dto';
|
||||||
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
||||||
|
@ -11,7 +11,12 @@ import {
|
||||||
} from 'picsur-shared/dist/dto/mimes.dto';
|
} from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.enum';
|
||||||
import { UsrPreference } from 'picsur-shared/dist/dto/usr-preferences.enum';
|
import { UsrPreference } from 'picsur-shared/dist/dto/usr-preferences.enum';
|
||||||
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
AsyncFailable,
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
import { FindResult } from 'picsur-shared/dist/types/find-result';
|
||||||
import { ParseFileType } from 'picsur-shared/dist/util/parse-mime';
|
import { ParseFileType } from 'picsur-shared/dist/util/parse-mime';
|
||||||
import { IsQOI } from 'qoi-img';
|
import { IsQOI } from 'qoi-img';
|
||||||
|
@ -229,7 +234,7 @@ export class ImageManagerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[ImageEntryVariant.MASTER]: result[ImageEntryVariant.MASTER]!,
|
[ImageEntryVariant.MASTER]: result[ImageEntryVariant.MASTER],
|
||||||
[ImageEntryVariant.ORIGINAL]: result[ImageEntryVariant.ORIGINAL],
|
[ImageEntryVariant.ORIGINAL]: result[ImageEntryVariant.ORIGINAL],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -268,7 +273,7 @@ export class ImageManagerService {
|
||||||
private getConvertHash(options: object) {
|
private getConvertHash(options: object) {
|
||||||
// Return a sha256 hash of the stringified options
|
// Return a sha256 hash of the stringified options
|
||||||
const stringified = JSON.stringify(options);
|
const stringified = JSON.stringify(options);
|
||||||
const hash = Crypto.createHash('sha256');
|
const hash = createHash('sha256');
|
||||||
hash.update(stringified);
|
hash.update(stringified);
|
||||||
const digest = hash.digest('hex');
|
const digest = hash.digest('hex');
|
||||||
return digest;
|
return digest;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -310,8 +312,8 @@ export class WebPInfo extends StreamParserWritable {
|
||||||
['VP8', 'VP8L', 'ANMF'].map((t) => [t, true] as [ChunkType, true]),
|
['VP8', 'VP8L', 'ANMF'].map((t) => [t, true] as [ChunkType, true]),
|
||||||
);
|
);
|
||||||
|
|
||||||
private offset: number = 0;
|
private offset = 0;
|
||||||
private maxSeekableOffset: number = -1; // same as file size - 1
|
private maxSeekableOffset = -1; // same as file size - 1
|
||||||
|
|
||||||
private pending?: {
|
private pending?: {
|
||||||
size: number;
|
size: number;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import isDocker from 'is-docker';
|
import isDocker from 'is-docker';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import { FallbackIfFailed, HasFailed } from 'picsur-shared/dist/types';
|
import { FallbackIfFailed, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||||
import { ImageDBService } from '../../collections/image-db/image-db.service';
|
import { ImageDBService } from '../../collections/image-db/image-db.service';
|
||||||
import { SystemStateDbService } from '../../collections/system-state-db/system-state-db.service';
|
import { SystemStateDbService } from '../../collections/system-state-db/system-state-db.service';
|
||||||
|
|
|
@ -24,7 +24,7 @@ export const UndeletableRolesList: string[] = UndeletableRolesTuple;
|
||||||
export const SystemRolesList = UndeletableRolesList;
|
export const SystemRolesList = UndeletableRolesList;
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
type SystemRole = typeof UndeletableRolesTuple[number];
|
type SystemRole = (typeof UndeletableRolesTuple)[number];
|
||||||
const SystemRoleDefaultsTyped: {
|
const SystemRoleDefaultsTyped: {
|
||||||
[key in SystemRole]: Permissions;
|
[key in SystemRole]: Permissions;
|
||||||
} = {
|
} = {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
ApiKeyUpdateResponse,
|
ApiKeyUpdateResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/apikeys.dto';
|
} from 'picsur-shared/dist/dto/api/apikeys.dto';
|
||||||
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { ApiKeyDbService } from '../../../collections/apikey-db/apikey-db.service';
|
import { ApiKeyDbService } from '../../../collections/apikey-db/apikey-db.service';
|
||||||
import {
|
import {
|
||||||
HasPermission,
|
HasPermission,
|
||||||
|
|
|
@ -3,8 +3,6 @@ import { NoPermissions } from '../../../decorators/permissions.decorator';
|
||||||
@Controller('api/experiment')
|
@Controller('api/experiment')
|
||||||
@NoPermissions()
|
@NoPermissions()
|
||||||
export class ExperimentController {
|
export class ExperimentController {
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
// @Get()
|
// @Get()
|
||||||
// @Returns(UserInfoResponse)
|
// @Returns(UserInfoResponse)
|
||||||
// async testRoute(
|
// async testRoute(
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
SupportedImageFileTypes,
|
SupportedImageFileTypes,
|
||||||
} from 'picsur-shared/dist/dto/mimes.dto';
|
} from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { TrackingState } from 'picsur-shared/dist/dto/tracking-state.enum';
|
import { TrackingState } from 'picsur-shared/dist/dto/tracking-state.enum';
|
||||||
import { FallbackIfFailed } from 'picsur-shared/dist/types';
|
import { FallbackIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { HostConfigService } from '../../../config/early/host.config.service';
|
import { HostConfigService } from '../../../config/early/host.config.service';
|
||||||
import { InfoConfigService } from '../../../config/late/info.config.service';
|
import { InfoConfigService } from '../../../config/late/info.config.service';
|
||||||
import { UsageConfigService } from '../../../config/late/usage.config.service';
|
import { UsageConfigService } from '../../../config/late/usage.config.service';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
UpdatePreferenceRequest,
|
UpdatePreferenceRequest,
|
||||||
UpdatePreferenceResponse,
|
UpdatePreferenceResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/pref.dto';
|
} from 'picsur-shared/dist/dto/api/pref.dto';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { SysPreferenceDbService } from '../../../collections/preference-db/sys-preference-db.service';
|
import { SysPreferenceDbService } from '../../../collections/preference-db/sys-preference-db.service';
|
||||||
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||||
import { Returns } from '../../../decorators/returns.decorator';
|
import { Returns } from '../../../decorators/returns.decorator';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
UpdatePreferenceRequest,
|
UpdatePreferenceRequest,
|
||||||
UpdatePreferenceResponse,
|
UpdatePreferenceResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/pref.dto';
|
} from 'picsur-shared/dist/dto/api/pref.dto';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UsrPreferenceDbService } from '../../../collections/preference-db/usr-preference-db.service';
|
import { UsrPreferenceDbService } from '../../../collections/preference-db/usr-preference-db.service';
|
||||||
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||||
import { ReqUserID } from '../../../decorators/request-user.decorator';
|
import { ReqUserID } from '../../../decorators/request-user.decorator';
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
RoleUpdateResponse,
|
RoleUpdateResponse,
|
||||||
SpecialRolesResponse,
|
SpecialRolesResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/roles.dto';
|
} from 'picsur-shared/dist/dto/api/roles.dto';
|
||||||
import { Fail, FT, ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { Fail, FT, ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { RoleDbService } from '../../../collections/role-db/role-db.service';
|
import { RoleDbService } from '../../../collections/role-db/role-db.service';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Controller, Logger, Post, Req, Res } from '@nestjs/common';
|
import { Controller, Logger, Post, Req, Res } from '@nestjs/common';
|
||||||
import { Throttle } from '@nestjs/throttler';
|
import { Throttle } from '@nestjs/throttler';
|
||||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
import { Fail, FT, ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { Fail, FT, ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UsageConfigService } from '../../../config/late/usage.config.service';
|
import { UsageConfigService } from '../../../config/late/usage.config.service';
|
||||||
import { NoPermissions } from '../../../decorators/permissions.decorator';
|
import { NoPermissions } from '../../../decorators/permissions.decorator';
|
||||||
import { ReturnsAnything } from '../../../decorators/returns.decorator';
|
import { ReturnsAnything } from '../../../decorators/returns.decorator';
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
UserUpdateRequest,
|
UserUpdateRequest,
|
||||||
UserUpdateResponse,
|
UserUpdateResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/user-manage.dto';
|
} from 'picsur-shared/dist/dto/api/user-manage.dto';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||||
import { Returns } from '../../../decorators/returns.decorator';
|
import { Returns } from '../../../decorators/returns.decorator';
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
UserRegisterResponse,
|
UserRegisterResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/user.dto';
|
} from 'picsur-shared/dist/dto/api/user.dto';
|
||||||
import type { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import type { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { ThrowIfFailed } from 'picsur-shared/dist/types';
|
import { ThrowIfFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../../collections/user-db/user-db.service';
|
||||||
import {
|
import {
|
||||||
NoPermissions,
|
NoPermissions,
|
||||||
|
|
|
@ -21,7 +21,12 @@ import {
|
||||||
ImageUploadResponse,
|
ImageUploadResponse,
|
||||||
} from 'picsur-shared/dist/dto/api/image-manage.dto';
|
} from 'picsur-shared/dist/dto/api/image-manage.dto';
|
||||||
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
||||||
import { Fail, FT, HasFailed, ThrowIfFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
Fail,
|
||||||
|
FT,
|
||||||
|
HasFailed,
|
||||||
|
ThrowIfFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { PostFiles } from '../../decorators/multipart/multipart.decorator';
|
import { PostFiles } from '../../decorators/multipart/multipart.decorator';
|
||||||
import type { FileIterator } from '../../decorators/multipart/postfiles.pipe';
|
import type { FileIterator } from '../../decorators/multipart/postfiles.pipe';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -7,7 +7,11 @@ import {
|
||||||
} from 'picsur-shared/dist/dto/api/image.dto';
|
} from 'picsur-shared/dist/dto/api/image.dto';
|
||||||
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
import { ImageEntryVariant } from 'picsur-shared/dist/dto/image-entry-variant.enum';
|
||||||
import { FileType2Mime } from 'picsur-shared/dist/dto/mimes.dto';
|
import { FileType2Mime } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { FT, IsFailure, ThrowIfFailed } from 'picsur-shared/dist/types';
|
import {
|
||||||
|
FT,
|
||||||
|
IsFailure,
|
||||||
|
ThrowIfFailed,
|
||||||
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { UserDbService } from '../../collections/user-db/user-db.service';
|
import { UserDbService } from '../../collections/user-db/user-db.service';
|
||||||
import { ImageFullIdParam } from '../../decorators/image-id/image-full-id.decorator';
|
import { ImageFullIdParam } from '../../decorators/image-id/image-full-id.decorator';
|
||||||
import { ImageIdParam } from '../../decorators/image-id/image-id.decorator';
|
import { ImageIdParam } from '../../decorators/image-id/image-id.decorator';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { readFile } from 'fs/promises';
|
import { readFile } from 'fs/promises';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { PackageRoot } from '../config/config.static';
|
import { PackageRoot } from '../config/config.static';
|
||||||
|
|
||||||
export const BrandingPath = resolve(PackageRoot, '../branding');
|
export const BrandingPath = resolve(PackageRoot, '../branding');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail, FT } from 'picsur-shared/dist/types/failable';
|
||||||
|
|
||||||
export async function GetNextAsync<T>(
|
export async function GetNextAsync<T>(
|
||||||
iterator: AsyncIterableIterator<T>,
|
iterator: AsyncIterableIterator<T>,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { ChildProcess, fork } from 'child_process';
|
import { ChildProcess, fork } from 'child_process';
|
||||||
import pTimeout from 'p-timeout';
|
import pTimeout from 'p-timeout';
|
||||||
import path from 'path';
|
import { dirname, join as pathJoin } from 'path';
|
||||||
import { FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
import { FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import {
|
import {
|
||||||
AsyncFailable,
|
AsyncFailable,
|
||||||
|
@ -9,7 +9,7 @@ import {
|
||||||
Failable,
|
Failable,
|
||||||
FT,
|
FT,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types/failable';
|
||||||
import { Sharp, SharpOptions } from 'sharp';
|
import { Sharp, SharpOptions } from 'sharp';
|
||||||
import {
|
import {
|
||||||
SharpWorkerFinishOptions,
|
SharpWorkerFinishOptions,
|
||||||
|
@ -22,13 +22,13 @@ import {
|
||||||
import { SharpResult } from './sharp/universal-sharp';
|
import { SharpResult } from './sharp/universal-sharp';
|
||||||
|
|
||||||
const moduleURL = new URL(import.meta.url);
|
const moduleURL = new URL(import.meta.url);
|
||||||
const __dirname = path.dirname(moduleURL.pathname);
|
const __dirname = dirname(moduleURL.pathname);
|
||||||
|
|
||||||
export class SharpWrapper {
|
export class SharpWrapper {
|
||||||
private readonly workerID: number = Math.floor(Math.random() * 100000);
|
private readonly workerID: number = Math.floor(Math.random() * 100000);
|
||||||
private readonly logger: Logger = new Logger('SharpWrapper' + this.workerID);
|
private readonly logger: Logger = new Logger('SharpWrapper' + this.workerID);
|
||||||
|
|
||||||
private static readonly WORKER_PATH = path.join(
|
private static readonly WORKER_PATH = pathJoin(
|
||||||
__dirname,
|
__dirname,
|
||||||
'./sharp',
|
'./sharp',
|
||||||
'sharp.worker.js',
|
'sharp.worker.js',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
import { FileType } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import posix from 'posix.js';
|
import { setrlimit } from 'posix.js';
|
||||||
import { Sharp } from 'sharp';
|
import { Sharp } from 'sharp';
|
||||||
import {
|
import {
|
||||||
SharpWorkerFinishOptions,
|
SharpWorkerFinishOptions,
|
||||||
|
@ -11,7 +11,7 @@ import {
|
||||||
import { UniversalSharpIn, UniversalSharpOut } from './universal-sharp';
|
import { UniversalSharpIn, UniversalSharpOut } from './universal-sharp';
|
||||||
|
|
||||||
export class SharpWorker {
|
export class SharpWorker {
|
||||||
private startTime: number = 0;
|
private startTime = 0;
|
||||||
private sharpi: Sharp | null = null;
|
private sharpi: Sharp | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -29,7 +29,7 @@ export class SharpWorker {
|
||||||
return this.purge('MEMORY_LIMIT_MB environment variable is not set');
|
return this.purge('MEMORY_LIMIT_MB environment variable is not set');
|
||||||
}
|
}
|
||||||
|
|
||||||
posix.setrlimit('data', {
|
setrlimit('data', {
|
||||||
soft: 1000 * 1000 * memoryLimit,
|
soft: 1000 * 1000 * memoryLimit,
|
||||||
hard: 1000 * 1000 * memoryLimit,
|
hard: 1000 * 1000 * memoryLimit,
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,8 +11,5 @@
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"emitDecoratorMetadata": true
|
"emitDecoratorMetadata": true
|
||||||
},
|
|
||||||
"ts-node": {
|
|
||||||
"experimentalSpecifierResolution": "node"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
module.exports = {
|
||||||
|
parserOptions: {
|
||||||
|
project: './tsconfig.base.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
ignorePatterns: ['src/environments', 'custom-webpack.config.js'],
|
||||||
|
root: false,
|
||||||
|
};
|
|
@ -14,11 +14,7 @@ export default {
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: {
|
options: {
|
||||||
presets: [
|
presets: [['@babel/preset-env']],
|
||||||
[
|
|
||||||
'@babel/preset-env',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve --host 0.0.0.0",
|
"start": "ng serve --host 0.0.0.0",
|
||||||
"build": "ng build",
|
"build": "ng build --verbose",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"purge": "rm -rf dist && rm -rf node_modules && rm -rf .angular"
|
"purge": "rm -rf dist && rm -rf node_modules && rm -rf .angular"
|
||||||
},
|
},
|
||||||
|
@ -47,7 +47,6 @@
|
||||||
"browserslist": "^4.21.7",
|
"browserslist": "^4.21.7",
|
||||||
"caniuse-lite": "^1.0.30001495",
|
"caniuse-lite": "^1.0.30001495",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"jwt-decode": "^3.1.2",
|
|
||||||
"material-icons": "^1.13.8",
|
"material-icons": "^1.13.8",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"ng-mat-select-infinite-scroll": "^4.0.0",
|
"ng-mat-select-infinite-scroll": "^4.0.0",
|
||||||
|
@ -62,5 +61,8 @@
|
||||||
"webpack-bundle-analyzer": "^4.9.0",
|
"webpack-bundle-analyzer": "^4.9.0",
|
||||||
"zod": "^3.21.4",
|
"zod": "^3.21.4",
|
||||||
"zone.js": "^0.13.0"
|
"zone.js": "^0.13.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@leteu/jwt-decoder": "^1.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,14 @@ export class AppComponent implements OnInit {
|
||||||
|
|
||||||
@ViewChild(MatSidenav) sidebar: MatSidenav;
|
@ViewChild(MatSidenav) sidebar: MatSidenav;
|
||||||
|
|
||||||
loading: boolean = false;
|
loading = false;
|
||||||
private loadingTimeout: number | null = null;
|
private loadingTimeout: number | null = null;
|
||||||
|
|
||||||
wrapContentWithContainer: boolean = true;
|
wrapContentWithContainer = true;
|
||||||
sidebarPortal: Portal<any> | undefined = undefined;
|
sidebarPortal: Portal<any> | undefined = undefined;
|
||||||
|
|
||||||
isDesktop: boolean = false;
|
isDesktop = false;
|
||||||
hasSidebar: boolean = false;
|
hasSidebar = false;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
|
@ -64,7 +64,7 @@ export class AppComponent implements OnInit {
|
||||||
if (event instanceof NavigationEnd) {
|
if (event instanceof NavigationEnd) {
|
||||||
this.loadingEnd();
|
this.loadingEnd();
|
||||||
}
|
}
|
||||||
if (event instanceof NavigationEnd) this.onNavigationEnd(event);
|
if (event instanceof NavigationEnd) this.onNavigationEnd();
|
||||||
if (event instanceof NavigationError) this.onNavigationError(event);
|
if (event instanceof NavigationError) this.onNavigationError(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ export class AppComponent implements OnInit {
|
||||||
this.router.navigate(['/error/404'], { replaceUrl: true });
|
this.router.navigate(['/error/404'], { replaceUrl: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onNavigationEnd(event: NavigationEnd) {
|
private async onNavigationEnd() {
|
||||||
const data = this.routeData;
|
const data = this.routeData;
|
||||||
this.wrapContentWithContainer = !data.noContainer;
|
this.wrapContentWithContainer = !data.noContainer;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ import {
|
||||||
MatFormFieldAppearance,
|
MatFormFieldAppearance,
|
||||||
SubscriptSizing,
|
SubscriptSizing,
|
||||||
} from '@angular/material/form-field';
|
} from '@angular/material/form-field';
|
||||||
import { FT, Fail } from 'picsur-shared/dist/types';
|
import { FT, Fail } from 'picsur-shared/dist/types/failable';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
import { ClipboardService } from 'src/app/util/clipboard.service';
|
import { ClipboardService } from '../../util/clipboard.service';
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
import { ErrorService } from '../../util/error-manager/error.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'copy-field',
|
selector: 'copy-field',
|
||||||
|
@ -17,11 +17,11 @@ export class CopyFieldComponent {
|
||||||
private readonly logger = new Logger(CopyFieldComponent.name);
|
private readonly logger = new Logger(CopyFieldComponent.name);
|
||||||
|
|
||||||
// Two parameters: name, value
|
// Two parameters: name, value
|
||||||
@Input() label: string = 'Loading...';
|
@Input() label = 'Loading...';
|
||||||
@Input() value: string = 'Loading...';
|
@Input() value = 'Loading...';
|
||||||
|
|
||||||
@Input() showHideButton: boolean = false;
|
@Input() showHideButton = false;
|
||||||
@Input() hidden: boolean = false;
|
@Input() hidden = false;
|
||||||
|
|
||||||
@Input() color: 'primary' | 'accent' | 'warn' = 'primary';
|
@Input() color: 'primary' | 'accent' | 'warn' = 'primary';
|
||||||
@Input() appearance: MatFormFieldAppearance = 'outline';
|
@Input() appearance: MatFormFieldAppearance = 'outline';
|
||||||
|
|
|
@ -3,8 +3,9 @@ import { NgModule } from '@angular/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { ErrorManagerModule } from 'src/app/util/error-manager/error-manager.module';
|
|
||||||
import { CopyFieldComponent } from './copy-field.component';
|
import { CopyFieldComponent } from './copy-field.component';
|
||||||
|
import { ErrorManagerModule } from '../../util/error-manager/error-manager.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [CopyFieldComponent],
|
declarations: [CopyFieldComponent],
|
||||||
imports: [
|
imports: [
|
||||||
|
|
|
@ -5,11 +5,10 @@ import { Component, Input } from '@angular/core';
|
||||||
templateUrl: './fab.component.html',
|
templateUrl: './fab.component.html',
|
||||||
})
|
})
|
||||||
export class FabComponent {
|
export class FabComponent {
|
||||||
@Input('aria-label') ariaLabel: string = 'Floating Action Button';
|
@Input('aria-label') ariaLabel = 'Floating Action Button';
|
||||||
@Input() icon: string = 'add';
|
@Input() icon = 'add';
|
||||||
@Input() color: string = 'primary';
|
@Input() color = 'primary';
|
||||||
@Input('tooltip') tooltip: string;
|
@Input('tooltip') tooltip: string;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
@Input() onClick: () => void = () => {};
|
@Input() onClick: () => void = () => {};
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
[matTooltip]="tooltip"
|
[matTooltip]="tooltip"
|
||||||
matTooltipPosition="left"
|
matTooltipPosition="left"
|
||||||
[matTooltipDisabled]="!openManager.isOpen"
|
[matTooltipDisabled]="!openManager.isOpen"
|
||||||
(click)="click($event)"
|
(click)="click()"
|
||||||
aria-label=""
|
aria-label=""
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
|
|
@ -9,19 +9,19 @@ import { SpeedDialAnimation } from './speed-dial.animation';
|
||||||
animations: [SpeedDialAnimation],
|
animations: [SpeedDialAnimation],
|
||||||
})
|
})
|
||||||
export class SpeedDialComponent {
|
export class SpeedDialComponent {
|
||||||
@Input('aria-label') ariaLabel: string = 'Floating Action Button';
|
@Input('aria-label') ariaLabel = 'Floating Action Button';
|
||||||
|
|
||||||
@Input('icon') icon: string = 'add';
|
@Input('icon') icon = 'add';
|
||||||
@Input('icon-hover') iconHover: string = 'close';
|
@Input('icon-hover') iconHover = 'close';
|
||||||
@Input('color') color: string = 'primary';
|
@Input('color') color = 'primary';
|
||||||
@Input('open-on-hover') openOnHover: boolean = false;
|
@Input('open-on-hover') openOnHover = false;
|
||||||
@Input('tooltip') tooltip: string;
|
@Input('tooltip') tooltip: string;
|
||||||
|
|
||||||
@Output('main-click') clickEmitter = new Subject<void>();
|
@Output('main-click') clickEmitter = new Subject<void>();
|
||||||
|
|
||||||
public openManager = new OpenManager();
|
public openManager = new OpenManager();
|
||||||
|
|
||||||
private touchUntil: number = 0;
|
private touchUntil = 0;
|
||||||
|
|
||||||
@HostListener('document:touchstart', ['$event'])
|
@HostListener('document:touchstart', ['$event'])
|
||||||
@HostListener('document:touchend', ['$event'])
|
@HostListener('document:touchend', ['$event'])
|
||||||
|
@ -35,13 +35,13 @@ export class SpeedDialComponent {
|
||||||
|
|
||||||
@HostListener('document:click', ['$event'])
|
@HostListener('document:click', ['$event'])
|
||||||
@HostListener('document:keydown.escape', ['$event'])
|
@HostListener('document:keydown.escape', ['$event'])
|
||||||
anyClick(e: Event) {
|
anyClick() {
|
||||||
if (!this.openManager.isOpen || this.openManager.isAnimating) return;
|
if (!this.openManager.isOpen || this.openManager.isAnimating) return;
|
||||||
|
|
||||||
this.openManager.close();
|
this.openManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
click(e: MouseEvent) {
|
click() {
|
||||||
if (!this.openManager.isOpen) {
|
if (!this.openManager.isOpen) {
|
||||||
this.openManager.open();
|
this.openManager.open();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
OnInit,
|
OnInit,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { InfoService } from 'src/app/services/api/info.service';
|
import { InfoService } from '../../services/api/info.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-footer',
|
selector: 'app-footer',
|
||||||
|
@ -19,8 +19,8 @@ export class FooterComponent implements OnInit {
|
||||||
private readonly changeDetector: ChangeDetectorRef,
|
private readonly changeDetector: ChangeDetectorRef,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
isDemo: boolean = false;
|
isDemo = false;
|
||||||
version: string = 'Unkown Version';
|
version = 'Unkown Version';
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.subscribeInfo();
|
this.subscribeInfo();
|
||||||
|
|
|
@ -11,11 +11,11 @@ import { Router } from '@angular/router';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { PermissionService } from 'src/app/services/api/permission.service';
|
import { UserService } from '../../services/api/user.service';
|
||||||
import { UserService } from 'src/app/services/api/user.service';
|
import { PermissionService } from '../../services/api/permission.service';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
import { ErrorService } from '../../util/error-manager/error.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-header',
|
selector: 'app-header',
|
||||||
|
@ -38,17 +38,17 @@ export class HeaderComponent implements OnInit {
|
||||||
this._enableHamburger = value;
|
this._enableHamburger = value;
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
}
|
}
|
||||||
public _enableHamburger: boolean = true;
|
public _enableHamburger = true;
|
||||||
@Output('onHamburgerClick') onHamburgerClick = new EventEmitter<void>();
|
@Output('onHamburgerClick') onHamburgerClick = new EventEmitter<void>();
|
||||||
|
|
||||||
@Input('loading') public loading: boolean = false;
|
@Input('loading') public loading = false;
|
||||||
|
|
||||||
private currentUser: EUser | null = null;
|
private currentUser: EUser | null = null;
|
||||||
|
|
||||||
public canLogIn: boolean = false;
|
public canLogIn = false;
|
||||||
public canAccessSettings: boolean = false;
|
public canAccessSettings = false;
|
||||||
public canUpload: boolean = false;
|
public canUpload = false;
|
||||||
public canRegister: boolean = false;
|
public canRegister = false;
|
||||||
|
|
||||||
public get user() {
|
public get user() {
|
||||||
return this.currentUser;
|
return this.currentUser;
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { ErrorManagerModule } from 'src/app/util/error-manager/error-manager.module';
|
|
||||||
import { HeaderComponent } from './header.component';
|
import { HeaderComponent } from './header.component';
|
||||||
|
import { ErrorManagerModule } from '../../util/error-manager/error-manager.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { Directive, ElementRef, Inject } from '@angular/core';
|
import { Directive, ElementRef, Inject } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
boxExtractor,
|
|
||||||
ResizeObserverDirective,
|
|
||||||
ResizeObserverService,
|
|
||||||
RESIZE_OPTION_BOX,
|
RESIZE_OPTION_BOX,
|
||||||
|
ResizeObserverService,
|
||||||
|
boxExtractor,
|
||||||
} from '@ng-web-apis/resize-observer';
|
} from '@ng-web-apis/resize-observer';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { map, Observable } from 'rxjs';
|
import { Observable, map } from 'rxjs';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[masonry-item]',
|
selector: '[masonry-item]',
|
||||||
|
|
|
@ -12,9 +12,9 @@ import {
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { combineLatest, Subscription } from 'rxjs';
|
import { combineLatest, Subscription } from 'rxjs';
|
||||||
import { RemoveChildren } from 'src/app/util/remove-children';
|
|
||||||
import { Throttle } from 'src/app/util/throttle';
|
|
||||||
import { MasonryItemDirective } from './masonry-item.directive';
|
import { MasonryItemDirective } from './masonry-item.directive';
|
||||||
|
import { RemoveChildren } from '../../util/remove-children';
|
||||||
|
import { Throttle } from '../../util/throttle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'masonry',
|
selector: 'masonry',
|
||||||
|
@ -30,7 +30,7 @@ export class MasonryComponent implements AfterViewInit, OnDestroy {
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
}
|
}
|
||||||
public _column_count = 1;
|
public _column_count = 1;
|
||||||
@Input('update-speed') update_speed: number = 200;
|
@Input('update-speed') update_speed = 200;
|
||||||
|
|
||||||
@ContentChildren(MasonryItemDirective)
|
@ContentChildren(MasonryItemDirective)
|
||||||
private content: QueryList<MasonryItemDirective>;
|
private content: QueryList<MasonryItemDirective>;
|
||||||
|
@ -59,7 +59,7 @@ export class MasonryComponent implements AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
this.sizesSubscription = combineLatest(sizes)
|
this.sizesSubscription = combineLatest(sizes)
|
||||||
.pipe(Throttle(this.update_speed))
|
.pipe(Throttle(this.update_speed))
|
||||||
.subscribe((output) => {
|
.subscribe(() => {
|
||||||
this.resortItems(items);
|
this.resortItems(items);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ export class MasonryComponent implements AfterViewInit, OnDestroy {
|
||||||
RemoveChildren(columnsArray[i]);
|
RemoveChildren(columnsArray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnSizes = columnsArray.map((c) => 0);
|
const columnSizes = columnsArray.map(() => 0);
|
||||||
|
|
||||||
for (let i = 0; i < itemsArray.length; i++) {
|
for (let i = 0; i < itemsArray.length; i++) {
|
||||||
const item = itemsArray[i];
|
const item = itemsArray[i];
|
||||||
|
@ -84,7 +84,7 @@ export class MasonryComponent implements AfterViewInit, OnDestroy {
|
||||||
let smallestColumn = 0;
|
let smallestColumn = 0;
|
||||||
let smallestColumnSize = columnSizes[0];
|
let smallestColumnSize = columnSizes[0];
|
||||||
for (let j = columnSizes.length - 1; j >= 0; j--) {
|
for (let j = columnSizes.length - 1; j >= 0; j--) {
|
||||||
let better_j = (j + i) % columnSizes.length;
|
const better_j = (j + i) % columnSizes.length;
|
||||||
|
|
||||||
if (columnSizes[better_j] <= smallestColumnSize) {
|
if (columnSizes[better_j] <= smallestColumnSize) {
|
||||||
smallestColumn = better_j;
|
smallestColumn = better_j;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { Required } from 'src/app/models/decorators/required.decorator';
|
import { Required } from '../../models/decorators/required.decorator';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'paginator',
|
selector: 'paginator',
|
||||||
|
@ -13,18 +13,18 @@ export class PaginatorComponent implements OnInit {
|
||||||
this.calculateRanges();
|
this.calculateRanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
page: number = 1;
|
page = 1;
|
||||||
@Input('page') set pageInput(value: number) {
|
@Input('page') set pageInput(value: number) {
|
||||||
this.page = value;
|
this.page = value;
|
||||||
this.calculateRanges();
|
this.calculateRanges();
|
||||||
}
|
}
|
||||||
@Output('page') pageChange = new EventEmitter<number>();
|
@Output('page') pageChange = new EventEmitter<number>();
|
||||||
|
|
||||||
@Input('show-first-last') showFirstLast: boolean = true;
|
@Input('show-first-last') showFirstLast = true;
|
||||||
|
|
||||||
@Input('shown-pages') shownPages: number = 7;
|
@Input('shown-pages') shownPages = 7;
|
||||||
@Input('shown-first-pages') shownFirstPages: number = 1;
|
@Input('shown-first-pages') shownFirstPages = 1;
|
||||||
@Input('shown-last-pages') shownLastPages: number = 1;
|
@Input('shown-last-pages') shownLastPages = 1;
|
||||||
|
|
||||||
firstPagesRange: [number, number] | null = null;
|
firstPagesRange: [number, number] | null = null;
|
||||||
lastPagesRange: [number, number] | null = null;
|
lastPagesRange: [number, number] | null = null;
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { CommonModule } from '@angular/common';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
|
||||||
import { PaginatorComponent } from './paginator.component';
|
import { PaginatorComponent } from './paginator.component';
|
||||||
|
import { PipesModule } from '../../pipes/pipes.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [PaginatorComponent],
|
declarations: [PaginatorComponent],
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<mat-icon *ngIf="state === 'error'">broken_image</mat-icon>
|
<mat-icon *ngIf="state === 'error'">broken_image</mat-icon>
|
||||||
|
|
||||||
<mat-spinner
|
<mat-spinner
|
||||||
(nguiInview)="onInview($event)"
|
(nguiInview)="onInview()"
|
||||||
(nguiOutview)="onOutview($event)"
|
(nguiOutview)="onOutview()"
|
||||||
*ngIf="state === 'init' || state === 'loading'"
|
*ngIf="state === 'init' || state === 'loading'"
|
||||||
></mat-spinner>
|
></mat-spinner>
|
||||||
|
|
|
@ -5,16 +5,15 @@ import {
|
||||||
ElementRef,
|
ElementRef,
|
||||||
Input,
|
Input,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
SimpleChanges,
|
|
||||||
ViewChild,
|
ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FileType, ImageFileType } from 'picsur-shared/dist/dto/mimes.dto';
|
import { FileType, ImageFileType } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { URLRegex } from 'picsur-shared/dist/util/common-regex';
|
import { URLRegex } from 'picsur-shared/dist/util/common-regex';
|
||||||
import { ParseMime2FileType } from 'picsur-shared/dist/util/parse-mime';
|
import { ParseMime2FileType } from 'picsur-shared/dist/util/parse-mime';
|
||||||
import { ApiService } from 'src/app/services/api/api.service';
|
import { ApiService } from '../../services/api/api.service';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
import { QoiWorkerService } from 'src/app/workers/qoi-worker.service';
|
import { QoiWorkerService } from '../../workers/qoi-worker.service';
|
||||||
|
|
||||||
enum PicsurImgState {
|
enum PicsurImgState {
|
||||||
Init = 'init',
|
Init = 'init',
|
||||||
|
@ -48,12 +47,12 @@ export class PicsurImgComponent implements OnChanges {
|
||||||
private readonly changeDetector: ChangeDetectorRef,
|
private readonly changeDetector: ChangeDetectorRef,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(): void {
|
||||||
if (this.isInView) this.reload();
|
if (this.isInView) this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private reload() {
|
private reload() {
|
||||||
let url = this.imageURL ?? '';
|
const url = this.imageURL ?? '';
|
||||||
if (!URLRegex.test(url)) {
|
if (!URLRegex.test(url)) {
|
||||||
this.state = PicsurImgState.Loading;
|
this.state = PicsurImgState.Loading;
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
|
@ -68,7 +67,7 @@ export class PicsurImgComponent implements OnChanges {
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => this.logger.error);
|
.catch(this.logger.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async update(url: string): AsyncFailable<void> {
|
private async update(url: string): AsyncFailable<void> {
|
||||||
|
@ -111,7 +110,7 @@ export class PicsurImgComponent implements OnChanges {
|
||||||
return ParseMime2FileType(mime);
|
return ParseMime2FileType(mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
onInview(e: any) {
|
onInview() {
|
||||||
this.isInView = true;
|
this.isInView = true;
|
||||||
|
|
||||||
if (this.state === PicsurImgState.Init) {
|
if (this.state === PicsurImgState.Init) {
|
||||||
|
@ -120,7 +119,7 @@ export class PicsurImgComponent implements OnChanges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onOutview(e: any) {
|
onOutview() {
|
||||||
this.isInView = false;
|
this.isInView = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ import {
|
||||||
DecodedPref,
|
DecodedPref,
|
||||||
PrefValueType,
|
PrefValueType,
|
||||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||||
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { filter } from 'rxjs';
|
import { filter } from 'rxjs';
|
||||||
import { Required } from 'src/app/models/decorators/required.decorator';
|
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
|
||||||
import { Throttle } from 'src/app/util/throttle';
|
|
||||||
import { ZodTypeAny } from 'zod';
|
import { ZodTypeAny } from 'zod';
|
||||||
|
import { Required } from '../../models/decorators/required.decorator';
|
||||||
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
|
import { ErrorService } from '../../util/error-manager/error.service';
|
||||||
|
import { Throttle } from '../../util/throttle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pref-option',
|
selector: 'pref-option',
|
||||||
|
@ -40,8 +40,8 @@ export class PrefOptionComponent implements OnInit {
|
||||||
pref: PrefValueType,
|
pref: PrefValueType,
|
||||||
) => AsyncFailable<any>;
|
) => AsyncFailable<any>;
|
||||||
|
|
||||||
@Input() @Required name: string = '';
|
@Input() @Required name = '';
|
||||||
@Input() helpText: string = '';
|
@Input() helpText = '';
|
||||||
@Input() validator?: ZodTypeAny = undefined;
|
@Input() validator?: ZodTypeAny = undefined;
|
||||||
|
|
||||||
constructor(private readonly errorService: ErrorService) {}
|
constructor(private readonly errorService: ErrorService) {}
|
||||||
|
@ -96,7 +96,7 @@ export class PrefOptionComponent implements OnInit {
|
||||||
subscribeUpdate() {
|
subscribeUpdate() {
|
||||||
return this.formControl.valueChanges
|
return this.formControl.valueChanges
|
||||||
.pipe(
|
.pipe(
|
||||||
filter((value) => this.formControl.errors === null),
|
filter(() => this.formControl.errors === null),
|
||||||
Throttle(300),
|
Throttle(300),
|
||||||
)
|
)
|
||||||
.subscribe(this.updatePreference.bind(this));
|
.subscribe(this.updatePreference.bind(this));
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { ErrorManagerModule } from 'src/app/util/error-manager/error-manager.module';
|
|
||||||
import { PrefOptionComponent } from './pref-option.component';
|
import { PrefOptionComponent } from './pref-option.component';
|
||||||
|
import { ErrorManagerModule } from '../../util/error-manager/error-manager.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { MatChipInputEvent } from '@angular/material/chips';
|
||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { Required } from 'src/app/models/decorators/required.decorator';
|
import { Required } from '../../models/decorators/required.decorator';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'values-picker',
|
selector: 'values-picker',
|
||||||
|
@ -18,7 +18,7 @@ export class ValuesPickerComponent implements OnInit, OnChanges {
|
||||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||||
|
|
||||||
// Ui niceties
|
// Ui niceties
|
||||||
@Input('name') @Required name: string = '';
|
@Input('name') @Required name = '';
|
||||||
public get nameCap(): string {
|
public get nameCap(): string {
|
||||||
return this.name.charAt(0).toUpperCase() + this.name.slice(1);
|
return this.name.charAt(0).toUpperCase() + this.name.slice(1);
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,14 @@ export class ValuesPickerComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
@AutoUnsubscribe()
|
@AutoUnsubscribe()
|
||||||
private subscribeInputValue() {
|
private subscribeInputValue() {
|
||||||
return this.inputControl.valueChanges.subscribe((value) => {
|
return this.inputControl.valueChanges.subscribe(() => {
|
||||||
this.updateSelectable();
|
this.updateSelectable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoUnsubscribe()
|
@AutoUnsubscribe()
|
||||||
private subscribeMyValue() {
|
private subscribeMyValue() {
|
||||||
return this.myControl.valueChanges.subscribe((value) => {
|
return this.myControl.valueChanges.subscribe(() => {
|
||||||
this.updateSelectable();
|
this.updateSelectable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
CanActivate,
|
CanActivate,
|
||||||
CanActivateChild,
|
CanActivateChild,
|
||||||
Router,
|
Router,
|
||||||
RouterStateSnapshot,
|
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
import { isPermissionsArray } from 'picsur-shared/dist/validators/permissions.validator';
|
import { isPermissionsArray } from 'picsur-shared/dist/validators/permissions.validator';
|
||||||
import { PRouteData } from '../models/dto/picsur-routes.dto';
|
import { PRouteData } from '../models/dto/picsur-routes.dto';
|
||||||
|
@ -24,18 +23,15 @@ export class PermissionGuard implements CanActivate, CanActivateChild {
|
||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async canActivateChild(
|
async canActivateChild(childRoute: ActivatedRouteSnapshot) {
|
||||||
childRoute: ActivatedRouteSnapshot,
|
return await this.can(childRoute);
|
||||||
state: RouterStateSnapshot,
|
|
||||||
) {
|
|
||||||
return await this.can(childRoute, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
async canActivate(route: ActivatedRouteSnapshot) {
|
||||||
return await this.can(route, state);
|
return await this.can(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async can(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
private async can(route: ActivatedRouteSnapshot) {
|
||||||
const requiredPermissions: string[] = this.nestedPermissions(route);
|
const requiredPermissions: string[] = this.nestedPermissions(route);
|
||||||
const allPermissionsArray = await this.staticInfo.getAllPermissions();
|
const allPermissionsArray = await this.staticInfo.getAllPermissions();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { TrackingState } from 'picsur-shared/dist/dto/tracking-state.enum';
|
import { TrackingState } from 'picsur-shared/dist/dto/tracking-state.enum';
|
||||||
|
|
||||||
export class ServerInfo {
|
export class ServerInfo {
|
||||||
production: boolean = false;
|
production = false;
|
||||||
demo: boolean = false;
|
demo = false;
|
||||||
version: string = '0.0.0';
|
version = '0.0.0';
|
||||||
host_override?: string;
|
host_override?: string;
|
||||||
tracking: {
|
tracking: {
|
||||||
state: TrackingState;
|
state: TrackingState;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
import { Fail, Failable, FT } from 'picsur-shared/dist/types';
|
import { Fail, Failable, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserPassModel } from '../forms-dto/userpass.dto';
|
import { UserPassModel } from '../forms-dto/userpass.dto';
|
||||||
import {
|
import {
|
||||||
CreatePasswordError,
|
CreatePasswordError,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
import { Fail, Failable, FT } from 'picsur-shared/dist/types';
|
import { Fail, Failable, FT } from 'picsur-shared/dist/types/failable';
|
||||||
import { UserPassModel } from '../forms-dto/userpass.dto';
|
import { UserPassModel } from '../forms-dto/userpass.dto';
|
||||||
import { Compare } from '../validators/compare.validator';
|
import { Compare } from '../validators/compare.validator';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
} from '../validators/user.validator';
|
} from '../validators/user.validator';
|
||||||
|
|
||||||
export class UpdateUserControl {
|
export class UpdateUserControl {
|
||||||
private id: string = '';
|
private id = '';
|
||||||
public username = new FormControl('', UsernameValidators);
|
public username = new FormControl('', UsernameValidators);
|
||||||
public password = new FormControl('', PasswordValidators);
|
public password = new FormControl('', PasswordValidators);
|
||||||
public roles = new FormControl<string[]>([]);
|
public roles = new FormControl<string[]>([]);
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||||
name: 'truncate',
|
name: 'truncate',
|
||||||
})
|
})
|
||||||
export class TruncatePipe implements PipeTransform {
|
export class TruncatePipe implements PipeTransform {
|
||||||
transform(text: string, length: number = 32, suffix: string = '...'): string {
|
transform(text: string, length = 32, suffix = '...'): string {
|
||||||
if (text.length > length) {
|
if (text.length > length) {
|
||||||
let truncated: string = text.substring(0, length).trim() + suffix;
|
const truncated: string = text.substring(0, length).trim() + suffix;
|
||||||
return truncated;
|
return truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { PRoutes } from 'src/app/models/dto/picsur-routes.dto';
|
|
||||||
import { E401Component } from './401.component';
|
import { E401Component } from './401.component';
|
||||||
import { E404Component } from './404.component';
|
import { E404Component } from './404.component';
|
||||||
import { ImageDeleteFailureComponent } from './delete-failure.component';
|
import { ImageDeleteFailureComponent } from './delete-failure.component';
|
||||||
import { ImageDeleteSuccessComponent } from './delete-success.component';
|
import { ImageDeleteSuccessComponent } from './delete-success.component';
|
||||||
|
import { PRoutes } from '../../models/dto/picsur-routes.dto';
|
||||||
|
|
||||||
const routes: PRoutes = [
|
const routes: PRoutes = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,19 +6,19 @@ import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
import { HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
|
Observable,
|
||||||
filter,
|
filter,
|
||||||
map,
|
map,
|
||||||
merge,
|
merge,
|
||||||
Observable,
|
|
||||||
switchMap,
|
switchMap,
|
||||||
timer,
|
timer,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import { ImageService } from 'src/app/services/api/image.service';
|
import { ImageService } from '../../services/api/image.service';
|
||||||
import { UserService } from 'src/app/services/api/user.service';
|
import { UserService } from '../../services/api/user.service';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
import { BootstrapService, BSScreenSize } from 'src/app/util/bootstrap.service';
|
import { BSScreenSize, BootstrapService } from '../../util/bootstrap.service';
|
||||||
import { DialogService } from 'src/app/util/dialog-manager/dialog.service';
|
import { DialogService } from '../../util/dialog-manager/dialog.service';
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
import { ErrorService } from '../../util/error-manager/error.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './images.component.html',
|
templateUrl: './images.component.html',
|
||||||
|
@ -39,8 +39,8 @@ export class ImagesComponent implements OnInit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
page: number = 1;
|
page = 1;
|
||||||
pages: number = 1;
|
pages = 1;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly route: ActivatedRoute,
|
private readonly route: ActivatedRoute,
|
||||||
|
@ -110,7 +110,7 @@ export class ImagesComponent implements OnInit {
|
||||||
merge(
|
merge(
|
||||||
...images
|
...images
|
||||||
.filter((i) => i.expires_at !== null)
|
.filter((i) => i.expires_at !== null)
|
||||||
.map((i) => timer(i.expires_at!).pipe(map(() => i))),
|
.map((i) => timer(i.expires_at ?? new Date(0)).pipe(map(() => i))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as Observable<EImage>;
|
) as Observable<EImage>;
|
||||||
|
|
|
@ -4,12 +4,12 @@ import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MomentModule } from 'ngx-moment';
|
import { MomentModule } from 'ngx-moment';
|
||||||
import { MasonryModule } from 'src/app/components/masonry/masonry.module';
|
import { MasonryModule } from '../../components/masonry/masonry.module';
|
||||||
import { PaginatorModule } from 'src/app/components/paginator/paginator.module';
|
import { PaginatorModule } from '../../components/paginator/paginator.module';
|
||||||
import { PicsurImgModule } from 'src/app/components/picsur-img/picsur-img.module';
|
import { PicsurImgModule } from '../../components/picsur-img/picsur-img.module';
|
||||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
import { PipesModule } from '../../pipes/pipes.module';
|
||||||
import { DialogManagerModule } from 'src/app/util/dialog-manager/dialog-manager.module';
|
import { DialogManagerModule } from '../../util/dialog-manager/dialog-manager.module';
|
||||||
import { ErrorManagerModule } from 'src/app/util/error-manager/error-manager.module';
|
import { ErrorManagerModule } from '../../util/error-manager/error-manager.module';
|
||||||
import { ImagesComponent } from './images.component';
|
import { ImagesComponent } from './images.component';
|
||||||
import { ImagesRoutingModule } from './images.routing.module';
|
import { ImagesRoutingModule } from './images.routing.module';
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
||||||
import { PermissionGuard } from 'src/app/guards/permission.guard';
|
|
||||||
import { PRoutes } from 'src/app/models/dto/picsur-routes.dto';
|
|
||||||
import { ImagesComponent } from './images.component';
|
import { ImagesComponent } from './images.component';
|
||||||
|
import { PermissionGuard } from '../../guards/permission.guard';
|
||||||
|
import { PRoutes } from '../../models/dto/picsur-routes.dto';
|
||||||
|
|
||||||
const routes: PRoutes = [
|
const routes: PRoutes = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
import { Fail, FT, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { ProcessingViewMeta } from 'src/app/models/dto/processing-view-meta.dto';
|
import { ProcessingViewMeta } from '../../models/dto/processing-view-meta.dto';
|
||||||
import { ApiService } from 'src/app/services/api/api.service';
|
import { ApiService } from '../../services/api/api.service';
|
||||||
import { ImageService } from 'src/app/services/api/image.service';
|
import { ImageService } from '../../services/api/image.service';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../services/logger/logger.service';
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
import { ErrorService } from '../../util/error-manager/error.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './processing.component.html',
|
templateUrl: './processing.component.html',
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { ErrorManagerModule } from 'src/app/util/error-manager/error-manager.module';
|
|
||||||
import { ProcessingComponent } from './processing.component';
|
import { ProcessingComponent } from './processing.component';
|
||||||
import { ProcessingRoutingModule } from './processing.routing.module';
|
import { ProcessingRoutingModule } from './processing.routing.module';
|
||||||
|
import { ErrorManagerModule } from '../../util/error-manager/error-manager.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [ProcessingComponent],
|
declarations: [ProcessingComponent],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { PRoutes } from 'src/app/models/dto/picsur-routes.dto';
|
|
||||||
import { ProcessingComponent } from './processing.component';
|
import { ProcessingComponent } from './processing.component';
|
||||||
|
import { PRoutes } from '../../models/dto/picsur-routes.dto';
|
||||||
|
|
||||||
const routes: PRoutes = [
|
const routes: PRoutes = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<mat-form-field class="editfield" appearance="outline" color="primary">
|
<mat-form-field class="editfield" appearance="outline" color="primary">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
<input matInput [formControl]="field" (change)="update($event)" />
|
<input matInput [formControl]="field" (change)="update()" />
|
||||||
<mat-error *ngIf="field.invalid">{{ getErrorMessage() }}</mat-error>
|
<mat-error *ngIf="field.invalid">{{ getErrorMessage() }}</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { FormControl, Validators } from '@angular/forms';
|
import { FormControl, Validators } from '@angular/forms';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../../../services/logger/logger.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings-apikey-editor',
|
selector: 'app-settings-apikey-editor',
|
||||||
|
@ -22,7 +22,7 @@ export class SettingsApiKeyEditorComponent {
|
||||||
Validators.maxLength(255),
|
Validators.maxLength(255),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
async update(event: Event) {
|
async update() {
|
||||||
if (this.field.invalid) {
|
if (this.field.invalid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,16 @@ import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||||
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
||||||
import { EApiKey } from 'picsur-shared/dist/entities/apikey.entity';
|
import { EApiKey } from 'picsur-shared/dist/entities/apikey.entity';
|
||||||
import { FT, Fail, HasFailed } from 'picsur-shared/dist/types';
|
import { FT, Fail, HasFailed } from 'picsur-shared/dist/types/failable';
|
||||||
import { BehaviorSubject, Subject } from 'rxjs';
|
import { BehaviorSubject, Subject } from 'rxjs';
|
||||||
import { ApiKeysService } from 'src/app/services/api/apikeys.service';
|
import { ApiKeysService } from '../../../services/api/apikeys.service';
|
||||||
import { UserService } from 'src/app/services/api/user.service';
|
import { UserService } from '../../../services/api/user.service';
|
||||||
import { Logger } from 'src/app/services/logger/logger.service';
|
import { Logger } from '../../../services/logger/logger.service';
|
||||||
import { BootstrapService } from 'src/app/util/bootstrap.service';
|
import { BootstrapService } from '../../../util/bootstrap.service';
|
||||||
import { ClipboardService } from 'src/app/util/clipboard.service';
|
import { ClipboardService } from '../../../util/clipboard.service';
|
||||||
import { DialogService } from 'src/app/util/dialog-manager/dialog.service';
|
import { DialogService } from '../../../util/dialog-manager/dialog.service';
|
||||||
import { ErrorService } from 'src/app/util/error-manager/error.service';
|
import { ErrorService } from '../../../util/error-manager/error.service';
|
||||||
import { Throttle } from 'src/app/util/throttle';
|
import { Throttle } from '../../../util/throttle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './settings-apikeys.component.html',
|
templateUrl: './settings-apikeys.component.html',
|
||||||
|
@ -31,7 +31,7 @@ export class SettingsApiKeysComponent implements OnInit {
|
||||||
|
|
||||||
public dataSubject = new BehaviorSubject<EApiKey[]>([]);
|
public dataSubject = new BehaviorSubject<EApiKey[]>([]);
|
||||||
public updateSubject = new Subject<PageEvent>();
|
public updateSubject = new Subject<PageEvent>();
|
||||||
public totalApiKeys: number = 0;
|
public totalApiKeys = 0;
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ export class SettingsApiKeysComponent implements OnInit {
|
||||||
return this.updateSubject
|
return this.updateSubject
|
||||||
.pipe(Throttle(500))
|
.pipe(Throttle(500))
|
||||||
.subscribe(async (pageEvent: PageEvent) => {
|
.subscribe(async (pageEvent: PageEvent) => {
|
||||||
let success = await this.fetchApiKeys(
|
const success = await this.fetchApiKeys(
|
||||||
pageEvent.pageSize,
|
pageEvent.pageSize,
|
||||||
pageEvent.pageIndex,
|
pageEvent.pageIndex,
|
||||||
);
|
);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue