First Commit
Build and Push Auth Portal Docker Image / build-and-push (push) Successful in 5m26s
Build and Push Auth Portal Docker Image / create-release (push) Skipped

This commit is contained in:
Denozordec
2026-07-18 13:27:37 +07:00
commit bac95bdb2e
154 changed files with 26610 additions and 0 deletions
+157
View File
@@ -0,0 +1,157 @@
import { eq } from 'drizzle-orm'
import { createHash, randomUUID } from 'node:crypto'
import type { AppDb } from './index.js'
import {
refreshSessions,
userApps,
userPermissions,
users,
} from './schema/index.js'
export type UserRow = typeof users.$inferSelect
export function hashToken(token: string): string {
return createHash('sha256').update(token).digest('hex')
}
export function listUsers(db: AppDb): UserRow[] {
return db.select().from(users).all()
}
export function getUserById(db: AppDb, id: string): UserRow | undefined {
return db.select().from(users).where(eq(users.id, id)).get()
}
export function getUserByEmail(
db: AppDb,
email: string,
): UserRow | undefined {
return db
.select()
.from(users)
.where(eq(users.email, email.toLowerCase()))
.get()
}
export function getUserApps(db: AppDb, userId: string): string[] {
return db
.select()
.from(userApps)
.where(eq(userApps.userId, userId))
.all()
.map((r) => r.appId)
}
export function getUserPermissions(db: AppDb, userId: string): string[] {
return db
.select()
.from(userPermissions)
.where(eq(userPermissions.userId, userId))
.all()
.map((r) => r.permission)
}
export function createUser(
db: AppDb,
input: {
email: string
name: string
passwordHash: string
isAdmin: boolean
},
): UserRow {
const now = new Date().toISOString()
const id = randomUUID()
db.insert(users)
.values({
id,
email: input.email.toLowerCase(),
name: input.name,
passwordHash: input.passwordHash,
isAdmin: input.isAdmin,
disabled: false,
createdAt: now,
updatedAt: now,
})
.run()
return getUserById(db, id)!
}
export function updateUser(
db: AppDb,
id: string,
patch: {
email?: string
name?: string
passwordHash?: string
isAdmin?: boolean
disabled?: boolean
},
): UserRow | undefined {
const existing = getUserById(db, id)
if (!existing) return undefined
const now = new Date().toISOString()
db.update(users)
.set({
email: patch.email?.toLowerCase() ?? existing.email,
name: patch.name ?? existing.name,
passwordHash: patch.passwordHash ?? existing.passwordHash,
isAdmin: patch.isAdmin ?? existing.isAdmin,
disabled: patch.disabled ?? existing.disabled,
updatedAt: now,
})
.where(eq(users.id, id))
.run()
return getUserById(db, id)
}
export function deleteUser(db: AppDb, id: string): boolean {
const result = db.delete(users).where(eq(users.id, id)).run()
return result.changes > 0
}
export function setUserAccess(
db: AppDb,
userId: string,
apps: string[],
permissions: string[],
): void {
db.delete(userApps).where(eq(userApps.userId, userId)).run()
db.delete(userPermissions).where(eq(userPermissions.userId, userId)).run()
for (const appId of apps) {
db.insert(userApps).values({ userId, appId }).run()
}
for (const permission of permissions) {
db.insert(userPermissions).values({ userId, permission }).run()
}
db.update(users)
.set({ updatedAt: new Date().toISOString() })
.where(eq(users.id, userId))
.run()
}
export function createRefreshSession(
db: AppDb,
userId: string,
rawToken: string,
expiresAt: Date,
): void {
db.insert(refreshSessions)
.values({
id: randomUUID(),
userId,
tokenHash: hashToken(rawToken),
expiresAt: expiresAt.toISOString(),
revokedAt: null,
createdAt: new Date().toISOString(),
})
.run()
}
export function revokeRefreshSession(db: AppDb, rawToken: string): void {
const now = new Date().toISOString()
db.update(refreshSessions)
.set({ revokedAt: now })
.where(eq(refreshSessions.tokenHash, hashToken(rawToken)))
.run()
}