reconsider logging levels
This commit is contained in:
parent
5ca8516560
commit
4612a9ea6f
|
@ -25,8 +25,8 @@ export class ImageDBService {
|
|||
|
||||
try {
|
||||
imageEntity = await this.imageRepository.save(imageEntity);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
return imageEntity;
|
||||
|
@ -48,8 +48,8 @@ export class ImageDBService {
|
|||
return found as B extends undefined
|
||||
? EImageBackend
|
||||
: Required<EImageBackend>;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,8 @@ export class ImageDBService {
|
|||
|
||||
if (found === undefined) return Fail('Images not found');
|
||||
return found;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,8 @@ export class ImageDBService {
|
|||
try {
|
||||
const result = await this.imageRepository.delete({ id });
|
||||
if (result.affected === 0) return Fail('Image not found');
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -89,8 +89,8 @@ export class ImageDBService {
|
|||
|
||||
try {
|
||||
await this.imageRepository.delete({});
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ export class PreferenceDefaultsService {
|
|||
if (envSecret) {
|
||||
return envSecret;
|
||||
} else {
|
||||
this.logger.warn(
|
||||
this.logger.log(
|
||||
'Since no JWT secret was provided, a random one will be generated and saved',
|
||||
);
|
||||
return generateRandomString(64);
|
||||
|
|
|
@ -45,9 +45,8 @@ export class SysPreferenceService {
|
|||
await this.sysPreferenceRepository.upsert(sysPreference, {
|
||||
conflictPaths: ['key'],
|
||||
});
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not save preference');
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
// Return
|
||||
|
@ -75,16 +74,14 @@ export class SysPreferenceService {
|
|||
}),
|
||||
() => this.saveDefault(validatedKey as SysPreference),
|
||||
);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not get preference');
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
// Validate
|
||||
const result = ESysPreferenceSchema.safeParse(foundSysPreference);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid preference');
|
||||
return Fail(result.error);
|
||||
}
|
||||
|
||||
// Return
|
||||
|
@ -157,8 +154,7 @@ export class SysPreferenceService {
|
|||
// It should already be valid, but these two validators might go out of sync
|
||||
const result = ESysPreferenceSchema.safeParse(verifySysPreference);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid preference');
|
||||
return Fail(result.error);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
|
|
|
@ -46,9 +46,8 @@ export class UsrPreferenceService {
|
|||
await this.usrPreferenceRepository.upsert(usrPreference, {
|
||||
conflictPaths: ['key', 'userId'],
|
||||
});
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not save preference');
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
// Return
|
||||
|
@ -80,16 +79,14 @@ export class UsrPreferenceService {
|
|||
}),
|
||||
() => this.saveDefault(userid, validatedKey as UsrPreference),
|
||||
);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not get preference');
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
// Validate
|
||||
const result = EUsrPreferenceSchema.safeParse(foundUsrPreference);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid preference');
|
||||
return Fail(result.error);
|
||||
}
|
||||
|
||||
// Return
|
||||
|
@ -198,8 +195,7 @@ export class UsrPreferenceService {
|
|||
// It should already be valid, but these two validators might go out of sync
|
||||
const result = EUsrPreferenceSchema.safeParse(verifySysPreference);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid preference');
|
||||
return Fail(result.error);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
|
|
|
@ -3,7 +3,11 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { EarlyConfigModule } from '../../config/early/early-config.module';
|
||||
import { HostConfigService } from '../../config/early/host.config.service';
|
||||
import { ImmutableRolesList, SystemRoleDefaults, UndeletableRolesList } from '../../models/constants/roles.const';
|
||||
import {
|
||||
ImmutableRolesList,
|
||||
SystemRoleDefaults,
|
||||
UndeletableRolesList
|
||||
} from '../../models/constants/roles.const';
|
||||
import { ERoleBackend } from '../../models/entities/role.entity';
|
||||
import { RolesService } from './role-db.service';
|
||||
|
||||
|
@ -42,7 +46,7 @@ export class RolesModule implements OnModuleInit {
|
|||
private async ensureSystemRolesExist() {
|
||||
// The UndeletableRolesList is also the list of systemroles
|
||||
for (const systemRole of UndeletableRolesList) {
|
||||
this.logger.debug(`Ensuring system role "${systemRole}" exists`);
|
||||
this.logger.verbose(`Ensuring system role "${systemRole}" exists`);
|
||||
|
||||
const exists = await this.rolesService.exists(systemRole);
|
||||
if (exists) continue;
|
||||
|
@ -65,7 +69,7 @@ export class RolesModule implements OnModuleInit {
|
|||
// They therefore do have to be kept up to date from the backend
|
||||
|
||||
for (const immutableRole of ImmutableRolesList) {
|
||||
this.logger.debug(
|
||||
this.logger.verbose(
|
||||
`Updating permissions for immutable role "${immutableRole}"`,
|
||||
);
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ export class RolesService {
|
|||
|
||||
try {
|
||||
return await this.rolesRepository.save(role, { reload: true });
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,8 +52,8 @@ export class RolesService {
|
|||
|
||||
try {
|
||||
return await this.rolesRepository.remove(roleToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,8 +118,8 @@ export class RolesService {
|
|||
|
||||
try {
|
||||
return await this.rolesRepository.save(roleToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +131,8 @@ export class RolesService {
|
|||
|
||||
if (!found) return Fail('Role not found');
|
||||
return found;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,8 +141,8 @@ export class RolesService {
|
|||
const found = await this.rolesRepository.find();
|
||||
if (!found) return Fail('No roles found');
|
||||
return found;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,8 +158,8 @@ export class RolesService {
|
|||
await this.rolesRepository.delete({
|
||||
name: In(UndeletableRolesList),
|
||||
});
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -172,8 +172,7 @@ export class RolesService {
|
|||
} else {
|
||||
const result = ERoleSchema.safeParse(role);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid role');
|
||||
return Fail(result.error);
|
||||
}
|
||||
// This is safe
|
||||
return result.data as ERoleBackend;
|
||||
|
|
|
@ -48,7 +48,7 @@ export class UsersModule implements OnModuleInit {
|
|||
password: string,
|
||||
roles: string[],
|
||||
) {
|
||||
this.logger.debug(`Ensuring user "${username}" exists`);
|
||||
this.logger.verbose(`Ensuring user "${username}" exists`);
|
||||
|
||||
const exists = await this.usersService.exists(username);
|
||||
if (exists) return;
|
||||
|
|
|
@ -64,8 +64,8 @@ export class UsersService {
|
|||
|
||||
try {
|
||||
return await this.usersRepository.save(user);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,8 +79,8 @@ export class UsersService {
|
|||
|
||||
try {
|
||||
return await this.usersRepository.remove(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ export class UsersService {
|
|||
|
||||
if (ImmutableUsersList.includes(userToModify.username)) {
|
||||
// Just fail silently
|
||||
this.logger.log("Can't modify system user");
|
||||
this.logger.verbose("User tried to modify system user, failed silently");
|
||||
return userToModify;
|
||||
}
|
||||
|
||||
|
@ -108,8 +108,8 @@ export class UsersService {
|
|||
|
||||
try {
|
||||
return await this.usersRepository.save(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,8 +124,7 @@ export class UsersService {
|
|||
.where('roles @> ARRAY[:role]', { role })
|
||||
.execute();
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return Fail("Couldn't remove role from everyone");
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -150,8 +149,8 @@ export class UsersService {
|
|||
|
||||
try {
|
||||
userToModify = await this.usersRepository.save(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
|
||||
return userToModify;
|
||||
|
@ -193,8 +192,8 @@ export class UsersService {
|
|||
|
||||
if (!found) return Fail('User not found');
|
||||
return found;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,8 +205,8 @@ export class UsersService {
|
|||
|
||||
if (!found) return Fail('User not found');
|
||||
return found as EUserBackend;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,8 +222,8 @@ export class UsersService {
|
|||
take: count,
|
||||
skip: count * page,
|
||||
});
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
} catch (e) {
|
||||
return Fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,254 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.dto';
|
||||
import {
|
||||
AsyncFailable,
|
||||
Fail,
|
||||
HasFailed,
|
||||
HasSuccess
|
||||
} from 'picsur-shared/dist/types';
|
||||
import { makeUnique } from 'picsur-shared/dist/util/unique';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Permissions } from '../../models/constants/permissions.const';
|
||||
import {
|
||||
DefaultRolesList,
|
||||
SoulBoundRolesList
|
||||
} from '../../models/constants/roles.const';
|
||||
import {
|
||||
ImmutableUsersList,
|
||||
LockedLoginUsersList,
|
||||
UndeletableUsersList
|
||||
} from '../../models/constants/special-users.const';
|
||||
import { EUserBackend } from '../../models/entities/user.entity';
|
||||
import { GetCols } from '../../models/util/collection';
|
||||
import { SysPreferenceService } from '../preference-db/sys-preference-db.service';
|
||||
import { RolesService } from '../role-db/role-db.service';
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
private readonly logger = new Logger('UsersService');
|
||||
|
||||
constructor(
|
||||
@InjectRepository(EUserBackend)
|
||||
private usersRepository: Repository<EUserBackend>,
|
||||
private rolesService: RolesService,
|
||||
private prefService: SysPreferenceService,
|
||||
) {}
|
||||
|
||||
// Creation and deletion
|
||||
|
||||
public async create(
|
||||
username: string,
|
||||
password: string,
|
||||
roles?: string[],
|
||||
// Add option to create "invalid" users, should only be used by system
|
||||
byPassRoleCheck?: boolean,
|
||||
): AsyncFailable<EUserBackend> {
|
||||
if (await this.exists(username)) return Fail('User already exists');
|
||||
|
||||
const strength = await this.getBCryptStrength();
|
||||
const hashedPassword = await bcrypt.hash(password, strength);
|
||||
|
||||
let user = new EUserBackend();
|
||||
user.username = username;
|
||||
user.hashedPassword = hashedPassword;
|
||||
if (byPassRoleCheck) {
|
||||
const rolesToAdd = roles ?? [];
|
||||
user.roles = makeUnique(rolesToAdd);
|
||||
} else {
|
||||
// Strip soulbound roles and add default roles
|
||||
const rolesToAdd = this.filterAddedRoles(roles ?? []);
|
||||
user.roles = makeUnique([...DefaultRolesList, ...rolesToAdd]);
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.usersRepository.save(user);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async delete(uuid: string): AsyncFailable<EUserBackend> {
|
||||
const userToModify = await this.findOne(uuid);
|
||||
if (HasFailed(userToModify)) return userToModify;
|
||||
|
||||
if (UndeletableUsersList.includes(userToModify.username)) {
|
||||
return Fail('Cannot delete system user');
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.usersRepository.remove(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Updating
|
||||
|
||||
public async setRoles(
|
||||
uuid: string,
|
||||
roles: string[],
|
||||
): AsyncFailable<EUserBackend> {
|
||||
const userToModify = await this.findOne(uuid);
|
||||
if (HasFailed(userToModify)) return userToModify;
|
||||
|
||||
if (ImmutableUsersList.includes(userToModify.username)) {
|
||||
// Just fail silently
|
||||
this.logger.log("Can't modify system user");
|
||||
return userToModify;
|
||||
}
|
||||
|
||||
const rolesToKeep = userToModify.roles.filter((role) =>
|
||||
SoulBoundRolesList.includes(role),
|
||||
);
|
||||
const rolesToAdd = this.filterAddedRoles(roles);
|
||||
const newRoles = makeUnique([...rolesToKeep, ...rolesToAdd]);
|
||||
userToModify.roles = newRoles;
|
||||
|
||||
try {
|
||||
return await this.usersRepository.save(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async removeRoleEveryone(role: string): AsyncFailable<true> {
|
||||
try {
|
||||
await this.usersRepository
|
||||
.createQueryBuilder('user')
|
||||
.update()
|
||||
.set({
|
||||
roles: () => 'ARRAY_REMOVE(roles, :role)',
|
||||
})
|
||||
.where('roles @> ARRAY[:role]', { role })
|
||||
.execute();
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return Fail("Couldn't remove role from everyone");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async getPermissions(uuid: string): AsyncFailable<Permissions> {
|
||||
const userToModify = await this.findOne(uuid);
|
||||
if (HasFailed(userToModify)) return userToModify;
|
||||
|
||||
return await this.rolesService.getPermissions(userToModify.roles);
|
||||
}
|
||||
|
||||
public async updatePassword(
|
||||
uuid: string,
|
||||
password: string,
|
||||
): AsyncFailable<EUserBackend> {
|
||||
let userToModify = await this.findOne(uuid);
|
||||
if (HasFailed(userToModify)) return userToModify;
|
||||
|
||||
const strength = await this.getBCryptStrength();
|
||||
userToModify.hashedPassword = await bcrypt.hash(password, strength);
|
||||
|
||||
try {
|
||||
userToModify = await this.usersRepository.save(userToModify);
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
|
||||
return userToModify;
|
||||
}
|
||||
|
||||
// Authentication
|
||||
|
||||
async authenticate(
|
||||
username: string,
|
||||
password: string,
|
||||
): AsyncFailable<EUserBackend> {
|
||||
const user = await this.findByUsername(username, true);
|
||||
if (HasFailed(user)) return user;
|
||||
|
||||
if (LockedLoginUsersList.includes(user.username)) {
|
||||
// Error should be kept in backend
|
||||
return Fail('Wrong username');
|
||||
}
|
||||
|
||||
if (!(await bcrypt.compare(password, user.hashedPassword ?? '')))
|
||||
return Fail('Wrong password');
|
||||
|
||||
return await this.findOne(user.id ?? '');
|
||||
}
|
||||
|
||||
// Listing
|
||||
|
||||
public async findByUsername(
|
||||
username: string,
|
||||
// Also fetch fields that aren't normally sent to the client
|
||||
// (e.g. hashed password)
|
||||
getPrivate: boolean = false,
|
||||
): AsyncFailable<EUserBackend> {
|
||||
try {
|
||||
const found = await this.usersRepository.findOne({
|
||||
where: { username },
|
||||
select: getPrivate ? GetCols(this.usersRepository) : undefined,
|
||||
});
|
||||
|
||||
if (!found) return Fail('User not found');
|
||||
return found;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async findOne(uuid: string): AsyncFailable<EUserBackend> {
|
||||
try {
|
||||
const found = await this.usersRepository.findOne({
|
||||
where: { id: uuid },
|
||||
});
|
||||
|
||||
if (!found) return Fail('User not found');
|
||||
return found as EUserBackend;
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async findMany(
|
||||
count: number,
|
||||
page: number,
|
||||
): AsyncFailable<EUserBackend[]> {
|
||||
if (count < 1 || page < 0) return Fail('Invalid page');
|
||||
if (count > 100) return Fail('Too many results');
|
||||
|
||||
try {
|
||||
return await this.usersRepository.find({
|
||||
take: count,
|
||||
skip: count * page,
|
||||
});
|
||||
} catch (e: any) {
|
||||
return Fail(e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
public async exists(username: string): Promise<boolean> {
|
||||
return HasSuccess(await this.findByUsername(username));
|
||||
}
|
||||
|
||||
// Internal
|
||||
|
||||
private filterAddedRoles(roles: string[]): string[] {
|
||||
const filteredRoles = roles.filter(
|
||||
(role) => !SoulBoundRolesList.includes(role),
|
||||
);
|
||||
|
||||
return filteredRoles;
|
||||
}
|
||||
|
||||
private async getBCryptStrength(): Promise<number> {
|
||||
const result = await this.prefService.getNumberPreference(
|
||||
SysPreference.BCryptStrength,
|
||||
);
|
||||
if (HasFailed(result)) {
|
||||
return 12;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -7,10 +7,10 @@ export class HostConfigService {
|
|||
private readonly logger = new Logger('HostConfigService');
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.logger.debug('Host: ' + this.getHost());
|
||||
this.logger.debug('Port: ' + this.getPort());
|
||||
this.logger.debug('Demo: ' + this.isDemo());
|
||||
this.logger.debug('Demo Interval: ' + this.getDemoInterval() / 1000 + 's');
|
||||
this.logger.log('Host: ' + this.getHost());
|
||||
this.logger.log('Port: ' + this.getPort());
|
||||
this.logger.log('Demo: ' + this.isDemo());
|
||||
this.logger.log('Demo Interval: ' + this.getDemoInterval() / 1000 + 's');
|
||||
}
|
||||
|
||||
public getHost(): string {
|
||||
|
|
|
@ -7,7 +7,7 @@ export class MultipartConfigService {
|
|||
private readonly logger = new Logger('MultipartConfigService');
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.logger.debug('Max file size: ' + this.getMaxFileSize());
|
||||
this.logger.log('Max file size: ' + this.getMaxFileSize());
|
||||
}
|
||||
|
||||
public getMaxFileSize(): number {
|
||||
|
|
|
@ -16,7 +16,7 @@ export class ServeStaticConfigService
|
|||
private defaultLocation = join(PackageRoot, '../frontend/dist');
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.logger.debug('Static directory: ' + this.getStaticDirectory());
|
||||
this.logger.log('Static directory: ' + this.getStaticDirectory());
|
||||
}
|
||||
|
||||
public getStaticDirectory(): string {
|
||||
|
|
|
@ -15,11 +15,12 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory {
|
|||
) {
|
||||
const varOptions = this.getTypeOrmServerOptions();
|
||||
|
||||
this.logger.debug('DB host: ' + varOptions.host);
|
||||
this.logger.debug('DB port: ' + varOptions.port);
|
||||
this.logger.debug('DB username: ' + varOptions.username);
|
||||
this.logger.debug('DB password: ' + varOptions.password);
|
||||
this.logger.debug('DB database: ' + varOptions.database);
|
||||
this.logger.log('DB host: ' + varOptions.host);
|
||||
this.logger.log('DB port: ' + varOptions.port);
|
||||
this.logger.log('DB database: ' + varOptions.database);
|
||||
|
||||
this.logger.verbose('DB username: ' + varOptions.username);
|
||||
this.logger.verbose('DB password: ' + varOptions.password);
|
||||
}
|
||||
|
||||
public getTypeOrmServerOptions() {
|
||||
|
|
|
@ -14,8 +14,8 @@ export class JwtConfigService implements JwtOptionsFactory {
|
|||
private async printDebug() {
|
||||
const secret = await this.getJwtSecret();
|
||||
const expiresIn = await this.getJwtExpiresIn();
|
||||
this.logger.debug('JWT secret: ' + secret);
|
||||
this.logger.debug('JWT expiresIn: ' + expiresIn);
|
||||
this.logger.verbose('JWT secret: ' + secret);
|
||||
this.logger.verbose('JWT expiresIn: ' + expiresIn);
|
||||
}
|
||||
|
||||
public async getJwtSecret(): Promise<string> {
|
||||
|
|
|
@ -28,7 +28,7 @@ export class MultiPartPipe implements PipeTransform {
|
|||
) {
|
||||
let zodSchema = (metadata?.metatype as ZodDtoStatic)?.zodSchema;
|
||||
if (!zodSchema) {
|
||||
this.logger.warn('Invalid scheme on multipart body');
|
||||
this.logger.error('Invalid scheme on multipart body');
|
||||
throw new InternalServerErrorException('Invalid scheme on backend');
|
||||
}
|
||||
|
||||
|
|
|
@ -47,14 +47,14 @@ export class MainAuthGuard extends AuthGuard(['jwt', 'guest']) {
|
|||
// These are the permissions required to access the route
|
||||
const permissions = this.extractPermissions(context);
|
||||
if (HasFailed(permissions)) {
|
||||
this.logger.warn('Route Permissions: ' + permissions.getReason());
|
||||
this.logger.error('Fetching route permission failed: ' + permissions.getReason());
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
// These are the permissions the user has
|
||||
const userPermissions = await this.usersService.getPermissions(user.id);
|
||||
if (HasFailed(userPermissions)) {
|
||||
this.logger.warn('User Permissions: ' + userPermissions.getReason());
|
||||
this.logger.warn('Fetching user permissions failed: ' + userPermissions.getReason());
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ export class DemoManagerModule implements OnModuleInit, OnModuleDestroy {
|
|||
|
||||
async onModuleInit() {
|
||||
if (this.hostConfigService.isDemo()) {
|
||||
this.logger.log('Demo mode enabled');
|
||||
this.logger.warn('Demo mode enabled, images are ephimeral');
|
||||
await this.setupDemoMode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ export class DemoManagerService {
|
|||
|
||||
public async setupRoles() {
|
||||
this.logger.warn(
|
||||
'Modifying roles for demo mode, this will not be reverted automatically',
|
||||
'Modifying roles for demo mode, this will have to be reverted manually',
|
||||
);
|
||||
// Could be done manually, but this makes settup up a demo instance quicker
|
||||
this.rolesService.addPermissions('guest', [Permission.ImageUpload]);
|
||||
|
@ -25,7 +25,7 @@ export class DemoManagerService {
|
|||
}
|
||||
|
||||
private async executeAsync() {
|
||||
this.logger.debug('Executing demo cleanup');
|
||||
this.logger.verbose('Executing demo cleanup');
|
||||
await this.imagesService.deleteAll(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ export class RolesController {
|
|||
|
||||
const success = await this.usersService.removeRoleEveryone(role.name);
|
||||
if (HasFailed(success)) {
|
||||
this.logger.warn(success.getReason());
|
||||
throw new InternalServerErrorException(
|
||||
'Could not remove role from users',
|
||||
);
|
||||
|
|
|
@ -40,7 +40,7 @@ export class PicsurImgComponent implements OnChanges {
|
|||
ngOnChanges(changes: SimpleChanges): void {
|
||||
let url = this.imageURL ?? '';
|
||||
if (URLRegex.test(url)) {
|
||||
this.update(url).catch((err) => this.logger.error(err));
|
||||
this.update(url).catch(this.logger.error);
|
||||
} else {
|
||||
this.state = PicsurImgState.Loading;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ export class LoginComponent implements OnInit {
|
|||
|
||||
const user = await this.userService.login(data.username, data.password);
|
||||
if (HasFailed(user)) {
|
||||
this.logger.warn(user.getReason());
|
||||
this.logger.error(user.getReason());
|
||||
this.utilService.showSnackBar(
|
||||
'Login failed, please try again',
|
||||
SnackBarType.Error
|
||||
|
|
|
@ -54,7 +54,7 @@ export class RegisterComponent implements OnInit {
|
|||
|
||||
const user = await this.userService.register(data.username, data.password);
|
||||
if (HasFailed(user)) {
|
||||
this.logger.warn(user.getReason());
|
||||
this.logger.error(user.getReason());
|
||||
this.utilService.showSnackBar(
|
||||
'Register failed, please try again',
|
||||
SnackBarType.Error
|
||||
|
@ -65,7 +65,7 @@ export class RegisterComponent implements OnInit {
|
|||
if (!this.userService.isLoggedIn) {
|
||||
const loginResult = await this.userService.login(data.username, data.password);
|
||||
if (HasFailed(loginResult)) {
|
||||
this.logger.warn(loginResult.getReason());
|
||||
this.logger.error(loginResult.getReason());
|
||||
this.utilService.showSnackBar(
|
||||
'Failed to login after register',
|
||||
SnackBarType.Error
|
||||
|
|
|
@ -44,7 +44,7 @@ export class ApiService {
|
|||
|
||||
const validateResult = sendSchema.safeParse(data);
|
||||
if (!validateResult.success) {
|
||||
this.logger.warn(validateResult.error);
|
||||
this.logger.error(validateResult.error);
|
||||
return Fail('Something went wrong');
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ export class ApiService {
|
|||
|
||||
const validateResult = resultSchema.safeParse(result);
|
||||
if (!validateResult.success) {
|
||||
this.logger.warn('result', validateResult.error);
|
||||
this.logger.error(validateResult.error);
|
||||
return Fail('Something went wrong');
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ export class ApiService {
|
|||
try {
|
||||
return await response.json();
|
||||
} catch (e) {
|
||||
this.logger.warn(e);
|
||||
this.logger.error(e);
|
||||
return Fail('Something went wrong');
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ export class ApiService {
|
|||
try {
|
||||
return await response.arrayBuffer();
|
||||
} catch (e) {
|
||||
this.logger.warn(e);
|
||||
this.logger.error(e);
|
||||
return Fail('Something went wrong');
|
||||
}
|
||||
}
|
||||
|
@ -133,9 +133,9 @@ export class ApiService {
|
|||
options.headers = headers;
|
||||
|
||||
return await window.fetch(url, options);
|
||||
} catch (error: any) {
|
||||
} catch (e) {
|
||||
this.errorSubject.next({
|
||||
error,
|
||||
error: e,
|
||||
url,
|
||||
});
|
||||
return Fail('Network Error');
|
||||
|
|
|
@ -59,7 +59,7 @@ export class PermissionService {
|
|||
return this.userService.live.pipe(Throttle(300)).subscribe(async (user) => {
|
||||
const permissions = await this.updatePermissions();
|
||||
if (HasFailed(permissions)) {
|
||||
this.logger.warn(permissions.getReason());
|
||||
this.logger.error(permissions.getReason());
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -44,7 +44,7 @@ export class UserService {
|
|||
|
||||
const user = await this.extractUser(apikey);
|
||||
if (HasFailed(user)) {
|
||||
this.logger.warn(user.getReason());
|
||||
this.logger.error(user.getReason());
|
||||
await this.logout();
|
||||
return;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ export class UserService {
|
|||
|
||||
const fetchedUser = await this.fetchUser();
|
||||
if (HasFailed(fetchedUser)) {
|
||||
this.logger.warn(fetchedUser.getReason());
|
||||
this.logger.error(fetchedUser.getReason());
|
||||
await this.logout();
|
||||
return;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ export class UserService {
|
|||
|
||||
const result = JwtDataSchema.safeParse(decoded);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
this.logger.error(result.error);
|
||||
return Fail('Invalid token data');
|
||||
}
|
||||
|
||||
|
|
|
@ -66,8 +66,18 @@ export class GlobalLogger {
|
|||
return;
|
||||
}
|
||||
|
||||
const processedArgs = args.map(a => {
|
||||
if (typeof a === 'string') {
|
||||
return a;
|
||||
} else if (a instanceof Error) {
|
||||
return a.message;
|
||||
} else {
|
||||
return a.toString();
|
||||
}
|
||||
})
|
||||
|
||||
const styles = LoggerStyles[level];
|
||||
const message = ['%c' + context.source, styles, ...args];
|
||||
const message = ['%c' + context.source, styles, ...processedArgs];
|
||||
console[LoggerFunctions[level]](...message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export class ApiErrorService {
|
|||
this.utilService.showSnackBar('Network Error', SnackBarType.Error);
|
||||
}
|
||||
|
||||
this.logger.warn(error.error);
|
||||
this.logger.error(error.error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,27 @@
|
|||
// -> Side effects go brrr
|
||||
|
||||
export class Failure {
|
||||
constructor(private readonly reason?: string) {}
|
||||
constructor(private readonly reason?: string, private readonly stack?: string) {}
|
||||
|
||||
getReason(): string {
|
||||
return this.reason ?? 'Unknown';
|
||||
}
|
||||
|
||||
getStack(): string {
|
||||
return this.stack ?? 'None';
|
||||
}
|
||||
}
|
||||
|
||||
export function Fail(reason?: string): Failure {
|
||||
return new Failure(reason);
|
||||
export function Fail(reason?: any): Failure {
|
||||
if (typeof reason === 'string') {
|
||||
return new Failure(reason);
|
||||
} else if(reason instanceof Error) {
|
||||
return new Failure(reason.message, reason.stack);
|
||||
} else if(reason instanceof Failure) {
|
||||
return reason;
|
||||
} else {
|
||||
return new Failure('Converted(' + reason + ')');
|
||||
}
|
||||
}
|
||||
|
||||
export type Failable<T> = T | Failure;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"strictNullChecks": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
|
||||
"skipLibCheck": true,
|
||||
"removeComments": true,
|
||||
|
|
Loading…
Reference in a new issue