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(), });