mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-17 17:29:41 +02:00
Applied formatting to 1487+ files using pnpm format:write - TypeScript/JavaScript files - Svelte components - Astro pages - JSON configs - Markdown docs 13 files still need manual review (Astro JSX comments)
104 lines
4.4 KiB
TypeScript
104 lines
4.4 KiB
TypeScript
import { pgSchema, uuid, text, timestamp, boolean, jsonb, pgEnum } from 'drizzle-orm/pg-core';
|
|
import { sql } from 'drizzle-orm';
|
|
|
|
export const authSchema = pgSchema('auth');
|
|
|
|
// Enum for user roles
|
|
export const userRoleEnum = pgEnum('user_role', ['user', 'admin', 'service']);
|
|
|
|
// Users table
|
|
export const users = authSchema.table('users', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
email: text('email').unique().notNull(),
|
|
emailVerified: boolean('email_verified').default(false).notNull(),
|
|
name: text('name'),
|
|
avatarUrl: text('avatar_url'),
|
|
role: userRoleEnum('role').default('user').notNull(),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
deletedAt: timestamp('deleted_at', { withTimezone: true }),
|
|
});
|
|
|
|
// Sessions table
|
|
export const sessions = authSchema.table('sessions', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
userId: uuid('user_id')
|
|
.references(() => users.id, { onDelete: 'cascade' })
|
|
.notNull(),
|
|
token: text('token').unique().notNull(),
|
|
refreshToken: text('refresh_token').unique().notNull(),
|
|
refreshTokenExpiresAt: timestamp('refresh_token_expires_at', { withTimezone: true }).notNull(),
|
|
ipAddress: text('ip_address'),
|
|
userAgent: text('user_agent'),
|
|
deviceId: text('device_id'),
|
|
deviceName: text('device_name'),
|
|
lastActivityAt: timestamp('last_activity_at', { withTimezone: true }).defaultNow().notNull(),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
|
revokedAt: timestamp('revoked_at', { withTimezone: true }),
|
|
});
|
|
|
|
// Accounts table (for OAuth providers)
|
|
export const accounts = authSchema.table('accounts', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
userId: uuid('user_id')
|
|
.references(() => users.id, { onDelete: 'cascade' })
|
|
.notNull(),
|
|
provider: text('provider').notNull(), // 'google', 'github', 'apple', etc.
|
|
providerAccountId: text('provider_account_id').notNull(),
|
|
accessToken: text('access_token'),
|
|
refreshToken: text('refresh_token'),
|
|
expiresAt: timestamp('expires_at', { withTimezone: true }),
|
|
tokenType: text('token_type'),
|
|
scope: text('scope'),
|
|
idToken: text('id_token'),
|
|
metadata: jsonb('metadata'),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
});
|
|
|
|
// Verification tokens (for email verification, password reset)
|
|
export const verificationTokens = authSchema.table('verification_tokens', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
userId: uuid('user_id')
|
|
.references(() => users.id, { onDelete: 'cascade' })
|
|
.notNull(),
|
|
token: text('token').unique().notNull(),
|
|
type: text('type').notNull(), // 'email_verification', 'password_reset'
|
|
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
usedAt: timestamp('used_at', { withTimezone: true }),
|
|
});
|
|
|
|
// Password table (separate for security)
|
|
export const passwords = authSchema.table('passwords', {
|
|
userId: uuid('user_id')
|
|
.primaryKey()
|
|
.references(() => users.id, { onDelete: 'cascade' }),
|
|
hashedPassword: text('hashed_password').notNull(),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
|
});
|
|
|
|
// Two-factor authentication
|
|
export const twoFactorAuth = authSchema.table('two_factor_auth', {
|
|
userId: uuid('user_id')
|
|
.primaryKey()
|
|
.references(() => users.id, { onDelete: 'cascade' }),
|
|
secret: text('secret').notNull(),
|
|
enabled: boolean('enabled').default(false).notNull(),
|
|
backupCodes: jsonb('backup_codes'), // Array of hashed backup codes
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
enabledAt: timestamp('enabled_at', { withTimezone: true }),
|
|
});
|
|
|
|
// Security events log
|
|
export const securityEvents = authSchema.table('security_events', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
|
eventType: text('event_type').notNull(), // 'login', 'logout', 'password_reset', 'suspicious_activity'
|
|
ipAddress: text('ip_address'),
|
|
userAgent: text('user_agent'),
|
|
metadata: jsonb('metadata'),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
});
|