Files
Lorenzo SanesiandClaude Opus 5.5 b83ce039fb
Deploy stack su Proxmox / deploy (push) Failing after 3s
Piattaforma ITI TECHNOLOGY: monorepo, Medusa, API, sito, area riservata e deploy
Monorepo npm con apps/public (Angular SSR), apps/private (Angular SPA),
apps/api (Fastify), packages/shared e packages/styles; Medusa 2.21 in medusa/;
infrastruttura Docker (Postgres PostGIS+pgvector, Redis, Caddy, backup) e
workflow Gitea Actions per il deploy via SSH a ogni push su master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jQyT6dR9czzGwqb7FkG6u
2026-10-20 09:30:48 +02:00

45 lines
1.8 KiB
TypeScript

import { getTableColumns } from "drizzle-orm"
import { describe, expect, it } from "vitest"
import { emailVerificationTokens, passwordResetTokens, refreshTokens, users } from "../src/db/schema/index.js"
import { hashPassword, verifyPassword } from "../src/services/password.js"
import { generateToken, hashToken } from "../src/services/tokens.js"
describe("token opachi", () => {
it("256 bit casuali, hash SHA-256 diverso dal token", () => {
const { token, hash } = generateToken()
expect(Buffer.from(token, "base64url")).toHaveLength(32)
expect(hash).toMatch(/^[0-9a-f]{64}$/)
expect(hash).not.toContain(token)
expect(hashToken(token)).toBe(hash)
expect(generateToken().token).not.toBe(token)
})
})
describe("password", () => {
it("argon2id, verifica ok/ko, hash malformato -> false", async () => {
const h = await hashPassword("una password lunga")
expect(h.startsWith("$argon2id$")).toBe(true)
expect(await verifyPassword(h, "una password lunga")).toBe(true)
expect(await verifyPassword(h, "sbagliata")).toBe(false)
expect(await verifyPassword("non-un-hash", "x")).toBe(false)
})
})
describe("schema: niente segreti in chiaro", () => {
it.each([
["refresh_tokens", refreshTokens],
["password_reset_tokens", passwordResetTokens],
["email_verification_tokens", emailVerificationTokens],
])("%s ha solo token_hash", (_name, table) => {
const columns = Object.values(getTableColumns(table)).map((c) => c.name)
expect(columns).toContain("token_hash")
expect(columns.filter((c) => /token|secret/.test(c) && c !== "token_hash")).toEqual([])
})
it("users ha password_hash e nessuna colonna password in chiaro", () => {
const columns = Object.values(getTableColumns(users)).map((c) => c.name)
expect(columns).toContain("password_hash")
expect(columns).not.toContain("password")
})
})