feat: enhance user schema with PGP encryption, GDPR fields, and 2FA support
This commit is contained in:
@@ -1,21 +1,45 @@
|
||||
import {pgTable, varchar, timestamp, uuid, pgEnum, index} from 'drizzle-orm/pg-core';
|
||||
import {pgTable, varchar, timestamp, uuid, pgEnum, index, boolean, customType} from 'drizzle-orm/pg-core';
|
||||
|
||||
// Type personnalisé pour les données chiffrées PGP (stockées en bytea dans Postgres)
|
||||
const pgpEncrypted = customType<{ data: string; driverData: string }>({
|
||||
dataType() {
|
||||
return 'bytea';
|
||||
},
|
||||
});
|
||||
|
||||
export const userStatus = pgEnum("user_status", ["active", "verification", "suspended", "pending", "deleted"])
|
||||
|
||||
export const users = pgTable('users', {
|
||||
status: userStatus('status').default('pending').notNull(),
|
||||
uuid: uuid().primaryKey().defaultRandom(),
|
||||
email: varchar('email', { length: 128 }).notNull().unique(),
|
||||
username: varchar('username', { length: 32 }).notNull().unique(),
|
||||
status: userStatus('status').default('pending').notNull(),
|
||||
|
||||
// Données Personnelles (PII) - Chiffrées nativement
|
||||
email: pgpEncrypted('email').notNull(),
|
||||
emailHash: varchar('email_hash', { length: 64 }).notNull().unique(), // Indexé pour recherche rapide et unicité
|
||||
displayName: varchar('display_name', { length: 32 }),
|
||||
|
||||
username: varchar('username', { length: 32 }).notNull().unique(),
|
||||
passwordHash: varchar('password_hash', { length: 72 }).notNull(),
|
||||
|
||||
// Sécurité
|
||||
twoFactorSecret: pgpEncrypted('two_factor_secret'),
|
||||
isTwoFactorEnabled: boolean('is_two_factor_enabled').notNull().default(false),
|
||||
|
||||
// RGPD & Conformité
|
||||
termsVersion: varchar('terms_version', { length: 16 }), // Version des CGU acceptées
|
||||
privacyVersion: varchar('privacy_version', { length: 16 }), // Version de la Privacy Policy acceptée
|
||||
gdprAcceptedAt: timestamp('gdpr_accepted_at', { withTimezone: true }),
|
||||
|
||||
// Dates de cycle de vie (Standards Entreprise)
|
||||
lastLoginAt: timestamp('last_login_at', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
gdprAcceptation: timestamp('gdpr_acceptation', { withTimezone: true }),
|
||||
deletedAt: timestamp('deleted_at', { withTimezone: true }), // Soft delete (Droit à l'oubli)
|
||||
}, (table) => ({
|
||||
uuidIdx: index('users_uuid_idx').on(table.uuid),
|
||||
emailIdx: index('users_email_idx').on(table.email),
|
||||
emailHashIdx: index('users_email_hash_idx').on(table.emailHash),
|
||||
usernameIdx: index('users_username_idx').on(table.username),
|
||||
statusIdx: index('users_status_idx').on(table.status),
|
||||
}));
|
||||
|
||||
export type UserInDb = typeof users.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user