feat(server/web): add oauth defaultStorageQuota and storageQuotaClaim (#7548)

* feat(server/web): add oauth defaultStorageQuota and storageQuotaClaim

* feat(server/web): fix format and use domain.util constants

* address some pr feedback

* simplify oauth storage quota logic

* adding tests and pr feedback

* chore: cleanup

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Sam Holton
2024-03-01 19:46:07 -05:00
committed by GitHub
parent 8b02f18e99
commit 7303fab9d9
17 changed files with 208 additions and 21 deletions
+28 -6
View File
@@ -7,11 +7,13 @@ import {
InternalServerErrorException,
UnauthorizedException,
} from '@nestjs/common';
import { isNumber, isString } from 'class-validator';
import cookieParser from 'cookie';
import { DateTime } from 'luxon';
import { IncomingHttpHeaders } from 'node:http';
import { ClientMetadata, Issuer, UserinfoResponse, custom, generators } from 'openid-client';
import { AccessCore, Permission } from '../access';
import { HumanReadableSize } from '../domain.util';
import {
IAccessRepository,
ICryptoRepository,
@@ -64,6 +66,12 @@ interface OAuthProfile extends UserinfoResponse {
email: string;
}
interface ClaimOptions<T> {
key: string;
default: T;
isValid: (value: unknown) => boolean;
}
@Injectable()
export class AuthService {
private access: AccessCore;
@@ -234,9 +242,11 @@ export class AuthService {
}
}
const { autoRegister, defaultStorageQuota, storageLabelClaim, storageQuotaClaim } = config.oauth;
// register new user
if (!user) {
if (!config.oauth.autoRegister) {
if (!autoRegister) {
this.logger.warn(
`Unable to register ${profile.email}. To enable set OAuth Auto Register to true in admin settings.`,
);
@@ -246,17 +256,24 @@ export class AuthService {
this.logger.log(`Registering new user: ${profile.email}/${profile.sub}`);
this.logger.verbose(`OAuth Profile: ${JSON.stringify(profile)}`);
let storageLabel: string | null = profile[config.oauth.storageLabelClaim as keyof OAuthProfile] as string;
if (typeof storageLabel !== 'string') {
storageLabel = null;
}
const storageLabel = this.getClaim(profile, {
key: storageLabelClaim,
default: '',
isValid: isString,
});
const storageQuota = this.getClaim(profile, {
key: storageQuotaClaim,
default: defaultStorageQuota,
isValid: (value: unknown) => isNumber(value) && value > 0,
});
const userName = profile.name ?? `${profile.given_name || ''} ${profile.family_name || ''}`;
user = await this.userCore.createUser({
name: userName,
email: profile.email,
oauthId: profile.sub,
storageLabel,
quotaSizeInBytes: storageQuota * HumanReadableSize.GiB || null,
storageLabel: storageLabel || null,
});
}
@@ -443,4 +460,9 @@ export class AuthService {
}
return [accessTokenCookie, authTypeCookie, isAuthenticatedCookie];
}
private getClaim<T>(profile: OAuthProfile, options: ClaimOptions<T>): T {
const value = profile[options.key as keyof OAuthProfile];
return options.isValid(value) ? (value as T) : options.default;
}
}