mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
151 lines
5.7 KiB
TypeScript
151 lines
5.7 KiB
TypeScript
import { createZodDto } from 'nestjs-zod';
|
|
import { AuthApiKey, AuthSession, AuthSharedLink, AuthUser, UserAdmin } from 'src/database';
|
|
import { ImmichCookie, UserMetadataKey } from 'src/enum';
|
|
import { UserMetadataItem } from 'src/types';
|
|
import { toEmail } from 'src/validation';
|
|
import z from 'zod';
|
|
|
|
export type CookieResponse = {
|
|
isSecure: boolean;
|
|
values: Array<{ key: ImmichCookie; value: string | null }>;
|
|
};
|
|
|
|
export const pinCodeRegex = /^\d{6}$/;
|
|
|
|
export type AuthDto = {
|
|
user: AuthUser;
|
|
apiKey?: AuthApiKey;
|
|
sharedLink?: AuthSharedLink;
|
|
session?: AuthSession;
|
|
};
|
|
|
|
const LoginCredentialSchema = z
|
|
.object({
|
|
email: toEmail.describe('User email').meta({ example: 'testuser@email.com' }),
|
|
password: z.string().describe('User password').meta({ example: 'password' }),
|
|
})
|
|
.meta({ id: 'LoginCredentialDto' });
|
|
|
|
const LoginResponseSchema = z
|
|
.object({
|
|
accessToken: z.string().describe('Access token'),
|
|
userId: z.string().describe('User ID'),
|
|
userEmail: toEmail.describe('User email'),
|
|
name: z.string().describe('User name'),
|
|
profileImagePath: z.string().describe('Profile image path'),
|
|
isAdmin: z.boolean().describe('Is admin user'),
|
|
shouldChangePassword: z.boolean().describe('Should change password'),
|
|
isOnboarded: z.boolean().describe('Is onboarded'),
|
|
})
|
|
.meta({ id: 'LoginResponseDto' });
|
|
|
|
export function mapLoginResponse(entity: UserAdmin, accessToken: string): LoginResponseDto {
|
|
const onboardingMetadata = entity.metadata.find(
|
|
(item): item is UserMetadataItem<UserMetadataKey.Onboarding> => item.key === UserMetadataKey.Onboarding,
|
|
)?.value;
|
|
|
|
return {
|
|
accessToken,
|
|
userId: entity.id,
|
|
userEmail: entity.email,
|
|
name: entity.name,
|
|
isAdmin: entity.isAdmin,
|
|
profileImagePath: entity.profileImagePath,
|
|
shouldChangePassword: entity.shouldChangePassword,
|
|
isOnboarded: onboardingMetadata?.isOnboarded ?? false,
|
|
};
|
|
}
|
|
|
|
const LogoutResponseSchema = z
|
|
.object({
|
|
successful: z.boolean().describe('Logout successful'),
|
|
redirectUri: z.string().describe('Redirect URI'),
|
|
})
|
|
.meta({ id: 'LogoutResponseDto' });
|
|
|
|
const SignUpSchema = LoginCredentialSchema.extend({
|
|
name: z.string().describe('User name').meta({ example: 'Admin' }),
|
|
}).meta({ id: 'SignUpDto' });
|
|
|
|
const ChangePasswordSchema = z
|
|
.object({
|
|
password: z.string().describe('Current password').meta({ example: 'password' }),
|
|
newPassword: z.string().min(8).describe('New password (min 8 characters)').meta({ example: 'password' }),
|
|
invalidateSessions: z.boolean().default(false).optional().describe('Invalidate all other sessions'),
|
|
})
|
|
.meta({ id: 'ChangePasswordDto' });
|
|
|
|
const PinCodeSetupSchema = z
|
|
.object({
|
|
pinCode: z.string().regex(pinCodeRegex).describe('PIN code (4-6 digits)').meta({ example: '123456' }),
|
|
})
|
|
.meta({ id: 'PinCodeSetupDto' });
|
|
|
|
const PinCodeResetSchema = z.object({
|
|
pinCode: z.string().regex(pinCodeRegex).optional().describe('New PIN code (4-6 digits)').meta({ example: '123456' }),
|
|
password: z
|
|
.string()
|
|
.optional()
|
|
.describe('User password (required if PIN code is not provided)')
|
|
.meta({ example: 'password' }),
|
|
});
|
|
|
|
const SessionUnlockSchema = PinCodeResetSchema.meta({ id: 'SessionUnlockDto' });
|
|
|
|
const PinCodeChangeSchema = PinCodeResetSchema.extend({
|
|
newPinCode: z.string().regex(pinCodeRegex).describe('New PIN code (4-6 digits)'),
|
|
}).meta({ id: 'PinCodeChangeDto' });
|
|
|
|
const ValidateAccessTokenResponseSchema = z
|
|
.object({
|
|
authStatus: z.boolean().describe('Authentication status'),
|
|
})
|
|
.meta({ id: 'ValidateAccessTokenResponseDto' });
|
|
|
|
const OAuthCallbackSchema = z
|
|
.object({
|
|
url: z.string().min(1).describe('OAuth callback URL'),
|
|
state: z.string().optional().describe('OAuth state parameter'),
|
|
codeVerifier: z.string().optional().describe('OAuth code verifier (PKCE)'),
|
|
})
|
|
.meta({ id: 'OAuthCallbackDto' });
|
|
|
|
const OAuthConfigSchema = z
|
|
.object({
|
|
redirectUri: z.string().describe('OAuth redirect URI'),
|
|
state: z.string().optional().describe('OAuth state parameter'),
|
|
codeChallenge: z.string().optional().describe('OAuth code challenge (PKCE)'),
|
|
})
|
|
.meta({ id: 'OAuthConfigDto' });
|
|
|
|
const OAuthAuthorizeResponseSchema = z
|
|
.object({
|
|
url: z.string().describe('OAuth authorization URL'),
|
|
})
|
|
.meta({ id: 'OAuthAuthorizeResponseDto' });
|
|
|
|
const AuthStatusResponseSchema = z
|
|
.object({
|
|
pinCode: z.boolean().describe('Has PIN code set'),
|
|
password: z.boolean().describe('Has password set'),
|
|
isElevated: z.boolean().describe('Is elevated session'),
|
|
expiresAt: z.string().optional().describe('Session expiration date'),
|
|
pinExpiresAt: z.string().optional().describe('PIN expiration date'),
|
|
})
|
|
.meta({ id: 'AuthStatusResponseDto' });
|
|
|
|
export class LoginCredentialDto extends createZodDto(LoginCredentialSchema) {}
|
|
export class LoginResponseDto extends createZodDto(LoginResponseSchema) {}
|
|
export class LogoutResponseDto extends createZodDto(LogoutResponseSchema) {}
|
|
export class SignUpDto extends createZodDto(SignUpSchema) {}
|
|
export class ChangePasswordDto extends createZodDto(ChangePasswordSchema) {}
|
|
export class PinCodeSetupDto extends createZodDto(PinCodeSetupSchema) {}
|
|
export class PinCodeResetDto extends createZodDto(PinCodeResetSchema) {}
|
|
export class SessionUnlockDto extends createZodDto(SessionUnlockSchema) {}
|
|
export class PinCodeChangeDto extends createZodDto(PinCodeChangeSchema) {}
|
|
export class ValidateAccessTokenResponseDto extends createZodDto(ValidateAccessTokenResponseSchema) {}
|
|
export class OAuthCallbackDto extends createZodDto(OAuthCallbackSchema) {}
|
|
export class OAuthConfigDto extends createZodDto(OAuthConfigSchema) {}
|
|
export class OAuthAuthorizeResponseDto extends createZodDto(OAuthAuthorizeResponseSchema) {}
|
|
export class AuthStatusResponseDto extends createZodDto(AuthStatusResponseSchema) {}
|