Feat add iam auth
This commit is contained in:
@@ -184,6 +184,11 @@ model AdminUser {
|
||||
/// Only ever set for role = SALES_EXPERT (D17).
|
||||
salesExpertProfile SalesExpertProfile?
|
||||
|
||||
/// Issued admin-panel tokens, recorded only while session tracking is on
|
||||
/// (AUTH_SESSION_TRACKING, or implicitly whenever the IAM is enabled) so a
|
||||
/// token can be revoked before it expires. See AdminSession.
|
||||
sessions AdminSession[]
|
||||
|
||||
@@index([role])
|
||||
@@index([userTypeId])
|
||||
@@index([avatarFileId])
|
||||
@@ -191,6 +196,94 @@ model AdminUser {
|
||||
@@index([lastName])
|
||||
}
|
||||
|
||||
/// An issued APP token (customer app / sales-expert app), so it can be revoked
|
||||
/// before it expires — the counterpart of AdminSession for the other token family.
|
||||
///
|
||||
/// WHY A SEPARATE TABLE AND NO FOREIGN KEY
|
||||
/// ---------------------------------------
|
||||
/// An app token's `sub` is a Customer id for a customer and an **AdminUser id**
|
||||
/// for a sales expert (D21). One FK cannot point at two tables, so the subject is
|
||||
/// stored as a plain id plus its type. The rows are short-lived operational data,
|
||||
/// not part of the accounting model, so the missing FK costs nothing here.
|
||||
model AppSession {
|
||||
id String @id @default(cuid())
|
||||
|
||||
/// The token's `jti` claim. Unique: one row per issued token.
|
||||
jti String @unique
|
||||
|
||||
/// Customer.id, or AdminUser.id when subjectType is "sales-expert".
|
||||
subjectId String
|
||||
subjectType String
|
||||
|
||||
mobile String?
|
||||
|
||||
/// Set when the login was confirmed by the central IAM: its session id (`sid`)
|
||||
/// and stable user id (`sub`), which is what a back-channel logout arrives with.
|
||||
iamSessionId String?
|
||||
iamSub String?
|
||||
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
expiresAt DateTime?
|
||||
lastSeenAt DateTime?
|
||||
|
||||
revokedAt DateTime?
|
||||
revokedReason String?
|
||||
|
||||
@@index([subjectId])
|
||||
@@index([iamSessionId])
|
||||
@@index([iamSub])
|
||||
@@index([expiresAt])
|
||||
}
|
||||
|
||||
/// An issued admin-panel JWT, so it can be revoked before it expires.
|
||||
///
|
||||
/// WHY THIS EXISTS
|
||||
/// ---------------
|
||||
/// The admin token is self-contained and valid for 12h, which means nothing —
|
||||
/// not disabling the account, not a central "sign out everywhere" — could cut a
|
||||
/// session short: the token kept working until it expired. With the central IAM
|
||||
/// in the loop that gap became visible (an IAM session revocation had no effect
|
||||
/// here), so every issued token now carries a `jti` recorded on this table and
|
||||
/// JwtStrategy refuses a token whose row is revoked.
|
||||
///
|
||||
/// Rows are written ONLY while tracking is enabled, and JwtStrategy only
|
||||
/// enforces them while it is enabled, so a deployment that does not want the
|
||||
/// extra lookup behaves exactly as before.
|
||||
model AdminSession {
|
||||
id String @id @default(cuid())
|
||||
|
||||
/// The token's `jti` claim. Unique: one row per issued token.
|
||||
jti String @unique
|
||||
|
||||
adminUserId String
|
||||
adminUser AdminUser @relation(fields: [adminUserId], references: [id], onDelete: Cascade)
|
||||
|
||||
/// Set when the login was verified by the IAM: its session id (`sid`) and the
|
||||
/// stable user id (`sub`) there. Back-channel logout arrives keyed by these —
|
||||
/// deliberately here rather than as columns on AdminUser, so enabling the
|
||||
/// feature needs no change to an existing table.
|
||||
iamSessionId String?
|
||||
iamSub String?
|
||||
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
expiresAt DateTime?
|
||||
lastSeenAt DateTime?
|
||||
|
||||
revokedAt DateTime?
|
||||
revokedReason String?
|
||||
|
||||
@@index([adminUserId])
|
||||
@@index([iamSessionId])
|
||||
@@index([iamSub])
|
||||
@@index([expiresAt])
|
||||
}
|
||||
|
||||
/// The sales-expert fields legacy kept on the `customers` row (type=1) and that
|
||||
/// were lost when a sales expert became an AdminUser (D17).
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user