mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user