feat(#4): Implement Authentik OIDC authentication with BetterAuth
- Integrated BetterAuth library for modern authentication - Added Session, Account, and Verification database tables - Created complete auth module with service, controller, guards, and decorators - Implemented shared authentication types in @mosaic/shared package - Added comprehensive test coverage (26 tests passing) - Documented type sharing strategy for monorepo - Updated environment configuration with OIDC and JWT settings Key architectural decisions: - BetterAuth over Passport.js for better TypeScript support - Separation of User (DB entity) vs AuthUser (client-safe subset) - Shared types package to prevent FE/BE drift - Factory pattern for auth config to use shared Prisma instance Ready for frontend integration (Issue #6). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Fixes #4
This commit is contained in:
92
packages/shared/src/types/auth.types.ts
Normal file
92
packages/shared/src/types/auth.types.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Authentication-related type definitions
|
||||
* Shared between frontend and backend for type safety
|
||||
*/
|
||||
|
||||
/**
|
||||
* Authenticated user information
|
||||
* This is the subset of user data that's safe to expose to the client
|
||||
*/
|
||||
export interface AuthUser {
|
||||
readonly id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
image?: string;
|
||||
emailVerified?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session information
|
||||
*/
|
||||
export interface Session {
|
||||
readonly id: string;
|
||||
userId: string;
|
||||
token: string;
|
||||
expiresAt: Date;
|
||||
ipAddress?: string;
|
||||
userAgent?: string;
|
||||
readonly createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth account information
|
||||
*/
|
||||
export interface Account {
|
||||
readonly id: string;
|
||||
userId: string;
|
||||
accountId: string;
|
||||
providerId: string;
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
idToken?: string;
|
||||
accessTokenExpiresAt?: Date;
|
||||
refreshTokenExpiresAt?: Date;
|
||||
scope?: string;
|
||||
readonly createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session data returned from authentication
|
||||
* This is what the frontend receives after successful authentication
|
||||
*/
|
||||
export interface AuthSession {
|
||||
user: AuthUser;
|
||||
session: {
|
||||
id: string;
|
||||
token: string;
|
||||
expiresAt: Date;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Login request payload
|
||||
*/
|
||||
export interface LoginRequest {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login response
|
||||
*/
|
||||
export interface LoginResponse {
|
||||
accessToken: string;
|
||||
user: AuthUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth provider types
|
||||
*/
|
||||
export type OAuthProvider = "authentik" | "google" | "github";
|
||||
|
||||
/**
|
||||
* OAuth callback query parameters
|
||||
*/
|
||||
export interface OAuthCallbackParams {
|
||||
code: string;
|
||||
state?: string;
|
||||
error?: string;
|
||||
error_description?: string;
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import type {
|
||||
export interface User extends BaseEntity {
|
||||
email: string;
|
||||
name: string;
|
||||
emailVerified: boolean;
|
||||
image: string | null;
|
||||
authProviderId: string | null;
|
||||
preferences: Record<string, unknown>;
|
||||
}
|
||||
|
||||
@@ -125,3 +125,6 @@ export * from "./enums";
|
||||
|
||||
// Export database entity types
|
||||
export * from "./database.types";
|
||||
|
||||
// Export authentication types
|
||||
export * from "./auth.types";
|
||||
|
||||
Reference in New Issue
Block a user