refactor: add fields

This commit is contained in:
Mauricio Siu
2025-02-13 01:42:58 -06:00
parent 74ee024cf9
commit 7c0d223e17
12 changed files with 10726 additions and 2 deletions

View File

@@ -0,0 +1 @@
ALTER TABLE "user_temp" ADD COLUMN "created_at" timestamp DEFAULT now();

View File

@@ -0,0 +1 @@
ALTER TABLE "user_temp" ALTER COLUMN "token" SET DEFAULT '';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -484,6 +484,20 @@
"when": 1739428942964, "when": 1739428942964,
"tag": "0068_sour_professor_monster", "tag": "0068_sour_professor_monster",
"breakpoints": true "breakpoints": true
},
{
"idx": 69,
"version": "7",
"when": 1739432476590,
"tag": "0069_known_aqueduct",
"breakpoints": true
},
{
"idx": 70,
"version": "7",
"when": 1739432513877,
"tag": "0070_overrated_the_stranger",
"breakpoints": true
} }
] ]
} }

View File

@@ -28,6 +28,8 @@
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@oslojs/encoding":"1.1.0",
"@oslojs/crypto":"1.0.1",
"drizzle-dbml-generator":"0.10.0", "drizzle-dbml-generator":"0.10.0",
"better-auth":"1.1.16", "better-auth":"1.1.16",
"rotating-file-stream": "3.2.3", "rotating-file-stream": "3.2.3",

View File

@@ -16,6 +16,7 @@ export const lucia = new Lucia(adapter, {
secure: false, secure: false,
}, },
}, },
sessionExpiresIn: new TimeSpan(1, "d"), sessionExpiresIn: new TimeSpan(1, "d"),
getUserAttributes: (attributes) => { getUserAttributes: (attributes) => {
return { return {

View File

@@ -73,14 +73,15 @@ export const users_temp = pgTable("user_temp", {
.primaryKey() .primaryKey()
.$defaultFn(() => nanoid()), .$defaultFn(() => nanoid()),
name: text("name").notNull().default(""), name: text("name").notNull().default(""),
token: text("token").notNull(), token: text("token").notNull().default(""),
isRegistered: boolean("isRegistered").notNull().default(false), isRegistered: boolean("isRegistered").notNull().default(false),
expirationDate: text("expirationDate") expirationDate: text("expirationDate")
.notNull() .notNull()
.$defaultFn(() => new Date().toISOString()), .$defaultFn(() => new Date().toISOString()),
createdAt: text("createdAt") createdAt2: text("createdAt")
.notNull() .notNull()
.$defaultFn(() => new Date().toISOString()), .$defaultFn(() => new Date().toISOString()),
createdAt: timestamp("created_at").defaultNow(),
canCreateProjects: boolean("canCreateProjects").notNull().default(false), canCreateProjects: boolean("canCreateProjects").notNull().default(false),
canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false), canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false),
canCreateServices: boolean("canCreateServices").notNull().default(false), canCreateServices: boolean("canCreateServices").notNull().default(false),

View File

@@ -5,6 +5,9 @@ import { admin, createAuthMiddleware, organization } from "better-auth/plugins";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { db } from "../db"; import { db } from "../db";
import * as schema from "../db/schema"; import * as schema from "../db/schema";
import { Scrypt } from "lucia";
const scrypt = new Scrypt();
export const auth = betterAuth({ export const auth = betterAuth({
database: drizzleAdapter(db, { database: drizzleAdapter(db, {
provider: "pg", provider: "pg",
@@ -12,6 +15,10 @@ export const auth = betterAuth({
}), }),
emailAndPassword: { emailAndPassword: {
enabled: true, enabled: true,
password: {
hash: scrypt.hash,
verify: scrypt.verify,
},
}, },
hooks: { hooks: {
after: createAuthMiddleware(async (ctx) => { after: createAuthMiddleware(async (ctx) => {

View File

@@ -0,0 +1,94 @@
// import {
// decodeHex,
// encodeBase32LowerCaseNoPadding,
// encodeHexLowerCase,
// } from "@oslojs/encoding";
// import { generateRandomString } from "@oslojs/crypto/random";
// import { constantTimeEqual } from "@oslojs/crypto/subtle";
// import { scrypt } from "./scrypt/index";
// import type { RandomReader } from "@oslojs/crypto/random";
// async function generateScryptKey(
// data: string,
// salt: string,
// blockSize = 16,
// ): Promise<Uint8Array> {
// const encodedData = new TextEncoder().encode(data);
// const encodedSalt = new TextEncoder().encode(salt);
// const keyUint8Array = await scrypt(encodedData, encodedSalt, {
// N: 16384,
// r: blockSize,
// p: 1,
// dkLen: 64,
// });
// return new Uint8Array(keyUint8Array);
// }
// const random: RandomReader = {
// read(bytes: Uint8Array): void {
// crypto.getRandomValues(bytes);
// },
// };
// export function generateId(length: number): string {
// const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
// return generateRandomString(random, alphabet, length);
// }
// export function generateIdFromEntropySize(size: number): string {
// const buffer = crypto.getRandomValues(new Uint8Array(size));
// return encodeBase32LowerCaseNoPadding(buffer);
// }
// export class Scrypt implements PasswordHashingAlgorithm {
// async hash(password: string): Promise<string> {
// const salt = encodeHexLowerCase(crypto.getRandomValues(new Uint8Array(16)));
// const key = await generateScryptKey(password.normalize("NFKC"), salt);
// return `${salt}:${encodeHexLowerCase(key)}`;
// }
// async verify(hash: string, password: string): Promise<boolean> {
// const parts = hash.split(":");
// if (parts.length !== 2) return false;
// const [salt, key] = parts;
// const targetKey = await generateScryptKey(password.normalize("NFKC"), salt);
// return constantTimeEqual(targetKey, decodeHex(key));
// }
// }
// export class LegacyScrypt implements PasswordHashingAlgorithm {
// async hash(password: string): Promise<string> {
// const salt = encodeHexLowerCase(crypto.getRandomValues(new Uint8Array(16)));
// const key = await generateScryptKey(password.normalize("NFKC"), salt);
// return `s2:${salt}:${encodeHexLowerCase(key)}`;
// }
// async verify(hash: string, password: string): Promise<boolean> {
// const parts = hash.split(":");
// if (parts.length === 2) {
// const [salt, key] = parts;
// const targetKey = await generateScryptKey(
// password.normalize("NFKC"),
// salt,
// 8,
// );
// const result = constantTimeEqual(targetKey, decodeHex(key));
// return result;
// }
// if (parts.length !== 3) return false;
// const [version, salt, key] = parts;
// if (version === "s2") {
// const targetKey = await generateScryptKey(
// password.normalize("NFKC"),
// salt,
// );
// return constantTimeEqual(targetKey, decodeHex(key));
// }
// return false;
// }
// }
// export interface PasswordHashingAlgorithm {
// hash(password: string): Promise<string>;
// verify(hash: string, password: string): Promise<boolean>;
// }

View File

@@ -0,0 +1 @@
//

31
pnpm-lock.yaml generated
View File

@@ -558,6 +558,12 @@ importers:
'@octokit/auth-app': '@octokit/auth-app':
specifier: ^6.0.4 specifier: ^6.0.4
version: 6.1.1 version: 6.1.1
'@oslojs/crypto':
specifier: 1.0.1
version: 1.0.1
'@oslojs/encoding':
specifier: 1.1.0
version: 1.1.0
'@react-email/components': '@react-email/components':
specifier: ^0.0.21 specifier: ^0.0.21
version: 0.0.21(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) version: 0.0.21(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -2164,6 +2170,18 @@ packages:
'@one-ini/wasm@0.1.1': '@one-ini/wasm@0.1.1':
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
'@oslojs/asn1@1.0.0':
resolution: {integrity: sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA==}
'@oslojs/binary@1.0.0':
resolution: {integrity: sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ==}
'@oslojs/crypto@1.0.1':
resolution: {integrity: sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ==}
'@oslojs/encoding@1.1.0':
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
'@peculiar/asn1-android@2.3.15': '@peculiar/asn1-android@2.3.15':
resolution: {integrity: sha512-8U2TIj59cRlSXTX2d0mzUKP7whfWGFMzTeC3qPgAbccXFrPNZLaDhpNEdG5U2QZ/tBv/IHlCJ8s+KYXpJeop6w==} resolution: {integrity: sha512-8U2TIj59cRlSXTX2d0mzUKP7whfWGFMzTeC3qPgAbccXFrPNZLaDhpNEdG5U2QZ/tBv/IHlCJ8s+KYXpJeop6w==}
@@ -8507,6 +8525,19 @@ snapshots:
'@one-ini/wasm@0.1.1': {} '@one-ini/wasm@0.1.1': {}
'@oslojs/asn1@1.0.0':
dependencies:
'@oslojs/binary': 1.0.0
'@oslojs/binary@1.0.0': {}
'@oslojs/crypto@1.0.1':
dependencies:
'@oslojs/asn1': 1.0.0
'@oslojs/binary': 1.0.0
'@oslojs/encoding@1.1.0': {}
'@peculiar/asn1-android@2.3.15': '@peculiar/asn1-android@2.3.15':
dependencies: dependencies:
'@peculiar/asn1-schema': 2.3.15 '@peculiar/asn1-schema': 2.3.15