@arch-cadre/core 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/core/auth/augment.cjs +71 -0
- package/dist/core/auth/augment.d.cts +20 -0
- package/dist/core/auth/augment.d.cts.map +1 -0
- package/dist/core/auth/augment.d.mts +20 -0
- package/dist/core/auth/augment.d.mts.map +1 -0
- package/dist/core/auth/augment.mjs +66 -0
- package/dist/core/auth/augment.mjs.map +1 -0
- package/dist/core/auth/email-verification.cjs +99 -0
- package/dist/core/auth/email-verification.d.cts +62 -0
- package/dist/core/auth/email-verification.d.cts.map +1 -0
- package/dist/core/auth/email-verification.d.mts +62 -0
- package/dist/core/auth/email-verification.d.mts.map +1 -0
- package/dist/core/auth/email-verification.mjs +92 -0
- package/dist/core/auth/email-verification.mjs.map +1 -0
- package/dist/core/auth/logic.cjs +224 -0
- package/dist/core/auth/logic.d.cts +110 -0
- package/dist/core/auth/logic.d.cts.map +1 -0
- package/dist/core/auth/logic.d.mts +110 -0
- package/dist/core/auth/logic.d.mts.map +1 -0
- package/dist/core/auth/logic.mjs +213 -0
- package/dist/core/auth/logic.mjs.map +1 -0
- package/dist/core/auth/password-reset.cjs +118 -0
- package/dist/core/auth/password-reset.d.cts +39 -0
- package/dist/core/auth/password-reset.d.cts.map +1 -0
- package/dist/core/auth/password-reset.d.mts +39 -0
- package/dist/core/auth/password-reset.d.mts.map +1 -0
- package/dist/core/auth/password-reset.mjs +111 -0
- package/dist/core/auth/password-reset.mjs.map +1 -0
- package/dist/core/auth/rbac.cjs +118 -0
- package/dist/core/auth/rbac.d.cts +61 -0
- package/dist/core/auth/rbac.d.cts.map +1 -0
- package/dist/core/auth/rbac.d.mts +61 -0
- package/dist/core/auth/rbac.d.mts.map +1 -0
- package/dist/core/auth/rbac.mjs +104 -0
- package/dist/core/auth/rbac.mjs.map +1 -0
- package/dist/core/auth/session.cjs +161 -0
- package/dist/core/auth/session.d.cts +54 -0
- package/dist/core/auth/session.d.cts.map +1 -0
- package/dist/core/auth/session.d.mts +54 -0
- package/dist/core/auth/session.d.mts.map +1 -0
- package/dist/core/auth/session.mjs +150 -0
- package/dist/core/auth/session.mjs.map +1 -0
- package/dist/core/auth/types.d.cts +55 -0
- package/dist/core/auth/types.d.cts.map +1 -0
- package/dist/core/auth/types.d.mts +55 -0
- package/dist/core/auth/types.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.cjs +27 -0
- package/dist/core/auth/utils/encode.d.cts +15 -0
- package/dist/core/auth/utils/encode.d.cts.map +1 -0
- package/dist/core/auth/utils/encode.d.mts +15 -0
- package/dist/core/auth/utils/encode.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.mjs +26 -0
- package/dist/core/auth/utils/encode.mjs.map +1 -0
- package/dist/core/auth/utils/encryption.cjs +67 -0
- package/dist/core/auth/utils/encryption.d.cts +28 -0
- package/dist/core/auth/utils/encryption.d.cts.map +1 -0
- package/dist/core/auth/utils/encryption.d.mts +28 -0
- package/dist/core/auth/utils/encryption.d.mts.map +1 -0
- package/dist/core/auth/utils/encryption.mjs +64 -0
- package/dist/core/auth/utils/encryption.mjs.map +1 -0
- package/dist/core/auth/validation.cjs +39 -0
- package/dist/core/auth/validation.d.cts +48 -0
- package/dist/core/auth/validation.d.cts.map +1 -0
- package/dist/core/auth/validation.d.mts +48 -0
- package/dist/core/auth/validation.d.mts.map +1 -0
- package/dist/core/auth/validation.mjs +31 -0
- package/dist/core/auth/validation.mjs.map +1 -0
- package/dist/core/bootstrap.cjs +32 -0
- package/dist/core/bootstrap.d.cts +5 -0
- package/dist/core/bootstrap.d.cts.map +1 -0
- package/dist/core/bootstrap.d.mts +5 -0
- package/dist/core/bootstrap.d.mts.map +1 -0
- package/dist/core/bootstrap.mjs +33 -0
- package/dist/core/bootstrap.mjs.map +1 -0
- package/dist/core/config.cjs +6 -0
- package/dist/core/config.d.cts +11 -0
- package/dist/core/config.d.cts.map +1 -0
- package/dist/core/config.d.mts +11 -0
- package/dist/core/config.d.mts.map +1 -0
- package/dist/core/config.mjs +6 -0
- package/dist/core/config.mjs.map +1 -0
- package/dist/core/config.server.cjs +60 -0
- package/dist/core/config.server.d.cts +16 -0
- package/dist/core/config.server.d.cts.map +1 -0
- package/dist/core/config.server.d.mts +16 -0
- package/dist/core/config.server.d.mts.map +1 -0
- package/dist/core/config.server.mjs +57 -0
- package/dist/core/config.server.mjs.map +1 -0
- package/dist/core/event-bus.cjs +48 -0
- package/dist/core/event-bus.d.cts +17 -0
- package/dist/core/event-bus.d.cts.map +1 -0
- package/dist/core/event-bus.d.mts +17 -0
- package/dist/core/event-bus.d.mts.map +1 -0
- package/dist/core/event-bus.mjs +48 -0
- package/dist/core/event-bus.mjs.map +1 -0
- package/dist/core/filesystem/service.cjs +43 -0
- package/dist/core/filesystem/service.d.cts +19 -0
- package/dist/core/filesystem/service.d.cts.map +1 -0
- package/dist/core/filesystem/service.d.mts +19 -0
- package/dist/core/filesystem/service.d.mts.map +1 -0
- package/dist/core/filesystem/service.mjs +43 -0
- package/dist/core/filesystem/service.mjs.map +1 -0
- package/dist/core/filesystem/types.d.cts +22 -0
- package/dist/core/filesystem/types.d.cts.map +1 -0
- package/dist/core/filesystem/types.d.mts +22 -0
- package/dist/core/filesystem/types.d.mts.map +1 -0
- package/dist/core/notifications/actions.cjs +36 -0
- package/dist/core/notifications/actions.d.cts +58 -0
- package/dist/core/notifications/actions.d.cts.map +1 -0
- package/dist/core/notifications/actions.d.mts +58 -0
- package/dist/core/notifications/actions.d.mts.map +1 -0
- package/dist/core/notifications/actions.mjs +33 -0
- package/dist/core/notifications/actions.mjs.map +1 -0
- package/dist/core/notifications/index.cjs +2 -0
- package/dist/core/notifications/index.mjs +4 -0
- package/dist/core/notifications/service.cjs +30 -0
- package/dist/core/notifications/service.d.cts +9 -0
- package/dist/core/notifications/service.d.cts.map +1 -0
- package/dist/core/notifications/service.d.mts +9 -0
- package/dist/core/notifications/service.d.mts.map +1 -0
- package/dist/core/notifications/service.mjs +31 -0
- package/dist/core/notifications/service.mjs.map +1 -0
- package/dist/core/notifications/types.d.cts +21 -0
- package/dist/core/notifications/types.d.cts.map +1 -0
- package/dist/core/notifications/types.d.mts +21 -0
- package/dist/core/notifications/types.d.mts.map +1 -0
- package/dist/core/setup.cjs +25 -0
- package/dist/core/setup.d.cts +9 -0
- package/dist/core/setup.d.cts.map +1 -0
- package/dist/core/setup.d.mts +9 -0
- package/dist/core/setup.d.mts.map +1 -0
- package/dist/core/setup.mjs +25 -0
- package/dist/core/setup.mjs.map +1 -0
- package/dist/core/types.d.cts +13 -0
- package/dist/core/types.d.cts.map +1 -0
- package/dist/core/types.d.mts +13 -0
- package/dist/core/types.d.mts.map +1 -0
- package/dist/index.cjs +30 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +6 -0
- package/dist/server/auth/email.cjs +24 -0
- package/dist/server/auth/email.d.cts +13 -0
- package/dist/server/auth/email.d.cts.map +1 -0
- package/dist/server/auth/email.d.mts +13 -0
- package/dist/server/auth/email.d.mts.map +1 -0
- package/dist/server/auth/email.mjs +23 -0
- package/dist/server/auth/email.mjs.map +1 -0
- package/dist/server/auth/password.cjs +37 -0
- package/dist/server/auth/password.d.cts +23 -0
- package/dist/server/auth/password.d.cts.map +1 -0
- package/dist/server/auth/password.d.mts +23 -0
- package/dist/server/auth/password.d.mts.map +1 -0
- package/dist/server/auth/password.mjs +34 -0
- package/dist/server/auth/password.mjs.map +1 -0
- package/dist/server/auth/user.cjs +165 -0
- package/dist/server/auth/user.d.cts +58 -0
- package/dist/server/auth/user.d.cts.map +1 -0
- package/dist/server/auth/user.d.mts +58 -0
- package/dist/server/auth/user.d.mts.map +1 -0
- package/dist/server/auth/user.mjs +153 -0
- package/dist/server/auth/user.mjs.map +1 -0
- package/dist/server/database/inject.cjs +24 -0
- package/dist/server/database/inject.d.cts +15 -0
- package/dist/server/database/inject.d.cts.map +1 -0
- package/dist/server/database/inject.d.mts +15 -0
- package/dist/server/database/inject.d.mts.map +1 -0
- package/dist/server/database/inject.mjs +23 -0
- package/dist/server/database/inject.mjs.map +1 -0
- package/dist/server/database/schema.cjs +163 -0
- package/dist/server/database/schema.d.cts +2962 -0
- package/dist/server/database/schema.d.cts.map +1 -0
- package/dist/server/database/schema.d.mts +2962 -0
- package/dist/server/database/schema.d.mts.map +1 -0
- package/dist/server/database/schema.mjs +151 -0
- package/dist/server/database/schema.mjs.map +1 -0
- package/dist/server/emails/index.cjs +32 -0
- package/dist/server/emails/index.d.cts +26 -0
- package/dist/server/emails/index.d.cts.map +1 -0
- package/dist/server/emails/index.d.mts +26 -0
- package/dist/server/emails/index.d.mts.map +1 -0
- package/dist/server/emails/index.mjs +29 -0
- package/dist/server/emails/index.mjs.map +1 -0
- package/dist/server.cjs +145 -0
- package/dist/server.d.cts +26 -0
- package/dist/server.d.mts +26 -0
- package/dist/server.mjs +23 -0
- package/package.json +60 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
let bcryptjs = require("bcryptjs");
|
|
5
|
+
bcryptjs = require_runtime.__toESM(bcryptjs);
|
|
6
|
+
|
|
7
|
+
//#region src/server/auth/password.ts
|
|
8
|
+
/**
|
|
9
|
+
* Hashes the password using bcrypt.
|
|
10
|
+
* @param password Password to be hashed.
|
|
11
|
+
* @returns Returns the hashed password.
|
|
12
|
+
*/
|
|
13
|
+
async function hashPassword(password) {
|
|
14
|
+
return await bcryptjs.default.hash(password, 10);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Verifies the password hash.
|
|
18
|
+
* @param hash bcrypt hash.
|
|
19
|
+
* @param password Password for comparison.
|
|
20
|
+
* @returns Returns true if the password is correct, false otherwise.
|
|
21
|
+
*/
|
|
22
|
+
async function verifyPasswordHash(hash, password) {
|
|
23
|
+
return await bcryptjs.default.compare(password, hash);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validates password strength.
|
|
27
|
+
* @param password Password to validate.
|
|
28
|
+
* @returns Returns true if the password meets complexity requirements.
|
|
29
|
+
*/
|
|
30
|
+
async function verifyPasswordStrength(password) {
|
|
31
|
+
return password.length >= 8 && password.length <= 255;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
exports.hashPassword = hashPassword;
|
|
36
|
+
exports.verifyPasswordHash = verifyPasswordHash;
|
|
37
|
+
exports.verifyPasswordStrength = verifyPasswordStrength;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/server/auth/password.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Hashes the password using bcrypt.
|
|
4
|
+
* @param password Password to be hashed.
|
|
5
|
+
* @returns Returns the hashed password.
|
|
6
|
+
*/
|
|
7
|
+
declare function hashPassword(password: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Verifies the password hash.
|
|
10
|
+
* @param hash bcrypt hash.
|
|
11
|
+
* @param password Password for comparison.
|
|
12
|
+
* @returns Returns true if the password is correct, false otherwise.
|
|
13
|
+
*/
|
|
14
|
+
declare function verifyPasswordHash(hash: string, password: string): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Validates password strength.
|
|
17
|
+
* @param password Password to validate.
|
|
18
|
+
* @returns Returns true if the password meets complexity requirements.
|
|
19
|
+
*/
|
|
20
|
+
declare function verifyPasswordStrength(password: string): Promise<boolean>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { hashPassword, verifyPasswordHash, verifyPasswordStrength };
|
|
23
|
+
//# sourceMappingURL=password.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.cts","names":[],"sources":["../../../src/server/auth/password.ts"],"mappings":";;AASA;;;;iBAAsB,YAAA,CAAa,QAAA,WAAmB,OAAA;AAYtD;;;;;;AAAA,iBAAsB,kBAAA,CACpB,IAAA,UACA,QAAA,WACC,OAAA;;;AAUH;;;iBAAsB,sBAAA,CACpB,QAAA,WACC,OAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/server/auth/password.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Hashes the password using bcrypt.
|
|
4
|
+
* @param password Password to be hashed.
|
|
5
|
+
* @returns Returns the hashed password.
|
|
6
|
+
*/
|
|
7
|
+
declare function hashPassword(password: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Verifies the password hash.
|
|
10
|
+
* @param hash bcrypt hash.
|
|
11
|
+
* @param password Password for comparison.
|
|
12
|
+
* @returns Returns true if the password is correct, false otherwise.
|
|
13
|
+
*/
|
|
14
|
+
declare function verifyPasswordHash(hash: string, password: string): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Validates password strength.
|
|
17
|
+
* @param password Password to validate.
|
|
18
|
+
* @returns Returns true if the password meets complexity requirements.
|
|
19
|
+
*/
|
|
20
|
+
declare function verifyPasswordStrength(password: string): Promise<boolean>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { hashPassword, verifyPasswordHash, verifyPasswordStrength };
|
|
23
|
+
//# sourceMappingURL=password.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.mts","names":[],"sources":["../../../src/server/auth/password.ts"],"mappings":";;AASA;;;;iBAAsB,YAAA,CAAa,QAAA,WAAmB,OAAA;AAYtD;;;;;;AAAA,iBAAsB,kBAAA,CACpB,IAAA,UACA,QAAA,WACC,OAAA;;;AAUH;;;iBAAsB,sBAAA,CACpB,QAAA,WACC,OAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import bcrypt from "bcryptjs";
|
|
4
|
+
|
|
5
|
+
//#region src/server/auth/password.ts
|
|
6
|
+
/**
|
|
7
|
+
* Hashes the password using bcrypt.
|
|
8
|
+
* @param password Password to be hashed.
|
|
9
|
+
* @returns Returns the hashed password.
|
|
10
|
+
*/
|
|
11
|
+
async function hashPassword(password) {
|
|
12
|
+
return await bcrypt.hash(password, 10);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Verifies the password hash.
|
|
16
|
+
* @param hash bcrypt hash.
|
|
17
|
+
* @param password Password for comparison.
|
|
18
|
+
* @returns Returns true if the password is correct, false otherwise.
|
|
19
|
+
*/
|
|
20
|
+
async function verifyPasswordHash(hash, password) {
|
|
21
|
+
return await bcrypt.compare(password, hash);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validates password strength.
|
|
25
|
+
* @param password Password to validate.
|
|
26
|
+
* @returns Returns true if the password meets complexity requirements.
|
|
27
|
+
*/
|
|
28
|
+
async function verifyPasswordStrength(password) {
|
|
29
|
+
return password.length >= 8 && password.length <= 255;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { hashPassword, verifyPasswordHash, verifyPasswordStrength };
|
|
34
|
+
//# sourceMappingURL=password.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.mjs","names":[],"sources":["../../../src/server/auth/password.ts"],"sourcesContent":["\"use server\";\n\nimport bcrypt from \"bcryptjs\";\n\n/**\n * Hashes the password using bcrypt.\n * @param password Password to be hashed.\n * @returns Returns the hashed password.\n */\nexport async function hashPassword(password: string): Promise<string> {\n const saltRounds = 10;\n return await bcrypt.hash(password, saltRounds);\n // return password;\n}\n\n/**\n * Verifies the password hash.\n * @param hash bcrypt hash.\n * @param password Password for comparison.\n * @returns Returns true if the password is correct, false otherwise.\n */\nexport async function verifyPasswordHash(\n hash: string,\n password: string,\n): Promise<boolean> {\n return await bcrypt.compare(password, hash);\n // return password === hash;\n}\n\n/**\n * Validates password strength.\n * @param password Password to validate.\n * @returns Returns true if the password meets complexity requirements.\n */\nexport async function verifyPasswordStrength(\n password: string,\n): Promise<boolean> {\n return password.length >= 8 && password.length <= 255;\n}\n"],"mappings":";;;;;;;;;;AASA,eAAsB,aAAa,UAAmC;AAEpE,QAAO,MAAM,OAAO,KAAK,UADN,GAC2B;;;;;;;;AAUhD,eAAsB,mBACpB,MACA,UACkB;AAClB,QAAO,MAAM,OAAO,QAAQ,UAAU,KAAK;;;;;;;AAS7C,eAAsB,uBACpB,UACkB;AAClB,QAAO,SAAS,UAAU,KAAK,SAAS,UAAU"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_inject = require('../database/inject.cjs');
|
|
5
|
+
const require_schema = require('../database/schema.cjs');
|
|
6
|
+
const require_index = require('../emails/index.cjs');
|
|
7
|
+
const require_password = require('./password.cjs');
|
|
8
|
+
const require_encode = require('../../core/auth/utils/encode.cjs');
|
|
9
|
+
const require_encryption = require('../../core/auth/utils/encryption.cjs');
|
|
10
|
+
let drizzle_orm = require("drizzle-orm");
|
|
11
|
+
|
|
12
|
+
//#region src/server/auth/user.ts
|
|
13
|
+
/**
|
|
14
|
+
* Validates the username input.
|
|
15
|
+
*/
|
|
16
|
+
async function verifyUsernameInput(username) {
|
|
17
|
+
return username.length > 3 && username.length < 32 && username.trim() === username;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new user with an initial recovery code and default 'user' role.
|
|
21
|
+
*/
|
|
22
|
+
async function createUser(email, username, password) {
|
|
23
|
+
const passwordHash = await require_password.hashPassword(password);
|
|
24
|
+
const recoveryCode = require_encode.generateRandomRecoveryCode();
|
|
25
|
+
const encryptedRecoveryCode = require_encryption.encryptString(recoveryCode);
|
|
26
|
+
return await require_inject.db.transaction(async (tx) => {
|
|
27
|
+
const [row] = await tx.insert(require_schema.userTable).values({
|
|
28
|
+
email,
|
|
29
|
+
name: username,
|
|
30
|
+
password: passwordHash,
|
|
31
|
+
recovery_code: Buffer.from(encryptedRecoveryCode)
|
|
32
|
+
}).returning();
|
|
33
|
+
if (!row) throw new Error("Failed to create user");
|
|
34
|
+
let [role] = await tx.select().from(require_schema.rolesTable).where((0, drizzle_orm.eq)(require_schema.rolesTable.name, "user"));
|
|
35
|
+
if (!role) [role] = await tx.insert(require_schema.rolesTable).values({
|
|
36
|
+
name: "user",
|
|
37
|
+
description: "Default user role"
|
|
38
|
+
}).returning();
|
|
39
|
+
await tx.insert(require_schema.usersToRolesTable).values({
|
|
40
|
+
userId: row.id,
|
|
41
|
+
roleId: role.id
|
|
42
|
+
});
|
|
43
|
+
await /* @__PURE__ */ require_index.sendRecoveryCode(row.email, recoveryCode);
|
|
44
|
+
return row;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new user from an OAuth provider.
|
|
49
|
+
*/
|
|
50
|
+
async function createOAuthUser(email, name, image) {
|
|
51
|
+
const encryptedRecoveryCode = require_encryption.encryptString(require_encode.generateRandomRecoveryCode());
|
|
52
|
+
return await require_inject.db.transaction(async (tx) => {
|
|
53
|
+
const [row] = await tx.insert(require_schema.userTable).values({
|
|
54
|
+
email,
|
|
55
|
+
name,
|
|
56
|
+
image,
|
|
57
|
+
emailVerifiedAt: /* @__PURE__ */ new Date(),
|
|
58
|
+
recovery_code: Buffer.from(encryptedRecoveryCode)
|
|
59
|
+
}).returning();
|
|
60
|
+
let [role] = await tx.select().from(require_schema.rolesTable).where((0, drizzle_orm.eq)(require_schema.rolesTable.name, "user"));
|
|
61
|
+
if (!role) [role] = await tx.insert(require_schema.rolesTable).values({
|
|
62
|
+
name: "user",
|
|
63
|
+
description: "Default user role"
|
|
64
|
+
}).returning();
|
|
65
|
+
await tx.insert(require_schema.usersToRolesTable).values({
|
|
66
|
+
userId: row.id,
|
|
67
|
+
roleId: role.id
|
|
68
|
+
});
|
|
69
|
+
return row;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns a user by ID.
|
|
74
|
+
*/
|
|
75
|
+
async function getUserById(userId) {
|
|
76
|
+
const [user] = await require_inject.db.select().from(require_schema.userTable).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
77
|
+
if (!user) return null;
|
|
78
|
+
const { password, recovery_code, ...safeUser } = user;
|
|
79
|
+
return safeUser;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Decrypts and returns the user's recovery code.
|
|
83
|
+
*/
|
|
84
|
+
async function getUserRecoverCode(userId) {
|
|
85
|
+
const [user] = await require_inject.db.select({ recovery_code: require_schema.userTable.recovery_code }).from(require_schema.userTable).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
86
|
+
if (!user || !user.recovery_code) throw new Error("Recovery code not found for user");
|
|
87
|
+
return require_encryption.decryptToString(user.recovery_code);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generates and sets a new recovery code for the user.
|
|
91
|
+
*/
|
|
92
|
+
async function resetUserRecoveryCode(userId) {
|
|
93
|
+
const recoveryCode = require_encode.generateRandomRecoveryCode();
|
|
94
|
+
const encrypted = require_encryption.encryptString(recoveryCode);
|
|
95
|
+
const [currentUser] = await require_inject.db.update(require_schema.userTable).set({ recovery_code: Buffer.from(encrypted) }).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId)).returning();
|
|
96
|
+
if (!currentUser) throw new Error("User not found");
|
|
97
|
+
await /* @__PURE__ */ require_index.sendRecoveryCode(currentUser.email, recoveryCode);
|
|
98
|
+
return recoveryCode;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Updates the user's password.
|
|
102
|
+
*/
|
|
103
|
+
async function updateUserPassword(userId, password) {
|
|
104
|
+
const passwordHash = await require_password.hashPassword(password);
|
|
105
|
+
await require_inject.db.update(require_schema.userTable).set({ password: passwordHash }).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Updates the user's name.
|
|
109
|
+
*/
|
|
110
|
+
async function updateUserName(userId, name) {
|
|
111
|
+
await require_inject.db.update(require_schema.userTable).set({ name }).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Updates the user's image.
|
|
115
|
+
*/
|
|
116
|
+
async function updateUserAwatar(userId, image) {
|
|
117
|
+
await require_inject.db.update(require_schema.userTable).set({ image }).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Updates the user's email and marks it as verified.
|
|
121
|
+
*/
|
|
122
|
+
async function updateUserEmailAndSetEmailAsVerified(userId, email) {
|
|
123
|
+
await require_inject.db.update(require_schema.userTable).set({
|
|
124
|
+
email,
|
|
125
|
+
emailVerifiedAt: /* @__PURE__ */ new Date()
|
|
126
|
+
}).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Sets the user as email verified if the provided email matches.
|
|
130
|
+
*/
|
|
131
|
+
async function setUserAsEmailVerifiedIfEmailMatches(userId, email) {
|
|
132
|
+
return (await require_inject.db.update(require_schema.userTable).set({ emailVerifiedAt: /* @__PURE__ */ new Date() }).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(require_schema.userTable.id, userId), (0, drizzle_orm.eq)(require_schema.userTable.email, email))).returning({ id: require_schema.userTable.id })).length > 0;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Returns the user's password hash.
|
|
136
|
+
*/
|
|
137
|
+
async function getUserPasswordHash(userId) {
|
|
138
|
+
const [user] = await require_inject.db.select({ password: require_schema.userTable.password }).from(require_schema.userTable).where((0, drizzle_orm.eq)(require_schema.userTable.id, userId));
|
|
139
|
+
if (!user) throw new Error("User not found");
|
|
140
|
+
return user.password;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns a user by email.
|
|
144
|
+
*/
|
|
145
|
+
async function getUserFromEmail(email) {
|
|
146
|
+
const [user] = await require_inject.db.select().from(require_schema.userTable).where((0, drizzle_orm.eq)(require_schema.userTable.email, email));
|
|
147
|
+
if (!user) return null;
|
|
148
|
+
const { password, recovery_code, ...safeUser } = user;
|
|
149
|
+
return safeUser;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//#endregion
|
|
153
|
+
exports.createOAuthUser = createOAuthUser;
|
|
154
|
+
exports.createUser = createUser;
|
|
155
|
+
exports.getUserById = getUserById;
|
|
156
|
+
exports.getUserFromEmail = getUserFromEmail;
|
|
157
|
+
exports.getUserPasswordHash = getUserPasswordHash;
|
|
158
|
+
exports.getUserRecoverCode = getUserRecoverCode;
|
|
159
|
+
exports.resetUserRecoveryCode = resetUserRecoveryCode;
|
|
160
|
+
exports.setUserAsEmailVerifiedIfEmailMatches = setUserAsEmailVerifiedIfEmailMatches;
|
|
161
|
+
exports.updateUserAwatar = updateUserAwatar;
|
|
162
|
+
exports.updateUserEmailAndSetEmailAsVerified = updateUserEmailAndSetEmailAsVerified;
|
|
163
|
+
exports.updateUserName = updateUserName;
|
|
164
|
+
exports.updateUserPassword = updateUserPassword;
|
|
165
|
+
exports.verifyUsernameInput = verifyUsernameInput;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { User } from "../../core/auth/types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/server/auth/user.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validates the username input.
|
|
6
|
+
*/
|
|
7
|
+
declare function verifyUsernameInput(username: string): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new user with an initial recovery code and default 'user' role.
|
|
10
|
+
*/
|
|
11
|
+
declare function createUser(email: string, username: string, password: string): Promise<User>;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new user from an OAuth provider.
|
|
14
|
+
*/
|
|
15
|
+
declare function createOAuthUser(email: string, name: string, image?: string): Promise<User>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a user by ID.
|
|
18
|
+
*/
|
|
19
|
+
declare function getUserById(userId: string): Promise<User | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Decrypts and returns the user's recovery code.
|
|
22
|
+
*/
|
|
23
|
+
declare function getUserRecoverCode(userId: string): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Generates and sets a new recovery code for the user.
|
|
26
|
+
*/
|
|
27
|
+
declare function resetUserRecoveryCode(userId: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Updates the user's password.
|
|
30
|
+
*/
|
|
31
|
+
declare function updateUserPassword(userId: string, password: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Updates the user's name.
|
|
34
|
+
*/
|
|
35
|
+
declare function updateUserName(userId: string, name: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Updates the user's image.
|
|
38
|
+
*/
|
|
39
|
+
declare function updateUserAwatar(userId: string, image: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Updates the user's email and marks it as verified.
|
|
42
|
+
*/
|
|
43
|
+
declare function updateUserEmailAndSetEmailAsVerified(userId: string, email: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Sets the user as email verified if the provided email matches.
|
|
46
|
+
*/
|
|
47
|
+
declare function setUserAsEmailVerifiedIfEmailMatches(userId: string, email: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Returns the user's password hash.
|
|
50
|
+
*/
|
|
51
|
+
declare function getUserPasswordHash(userId: string): Promise<string | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns a user by email.
|
|
54
|
+
*/
|
|
55
|
+
declare function getUserFromEmail(email: string): Promise<User | null>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createOAuthUser, createUser, getUserById, getUserFromEmail, getUserPasswordHash, getUserRecoverCode, resetUserRecoveryCode, setUserAsEmailVerifiedIfEmailMatches, updateUserAwatar, updateUserEmailAndSetEmailAsVerified, updateUserName, updateUserPassword, verifyUsernameInput };
|
|
58
|
+
//# sourceMappingURL=user.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.d.cts","names":[],"sources":["../../../src/server/auth/user.ts"],"mappings":";;;;;AAiBA;iBAAsB,mBAAA,CAAoB,QAAA,WAAmB,OAAA;;;;iBASvC,UAAA,CACpB,KAAA,UACA,QAAA,UACA,QAAA,WACC,OAAA,CAAQ,IAAA;;;;iBA+CW,eAAA,CACpB,KAAA,UACA,IAAA,UACA,KAAA,YACC,OAAA,CAAQ,IAAA;;;;iBAyCW,WAAA,CAAY,MAAA,WAAiB,OAAA,CAAQ,IAAA;;;AA7C3D;iBA2DsB,kBAAA,CAAmB,MAAA,WAAiB,OAAA;;;;iBAkBpC,qBAAA,CAAsB,MAAA,WAAiB,OAAA;;;;iBAuBvC,kBAAA,CACpB,MAAA,UACA,QAAA,WACC,OAAA;;AA1DH;;iBAwEsB,cAAA,CACpB,MAAA,UACA,IAAA,WACC,OAAA;;;;iBAWmB,gBAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;AA3EH;iBAuFsB,oCAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;;iBAamB,oCAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;;iBAemB,mBAAA,CACpB,MAAA,WACC,OAAA;AAlFH;;;AAAA,iBAoGsB,gBAAA,CAAiB,KAAA,WAAgB,OAAA,CAAQ,IAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { User } from "../../core/auth/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/server/auth/user.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validates the username input.
|
|
6
|
+
*/
|
|
7
|
+
declare function verifyUsernameInput(username: string): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new user with an initial recovery code and default 'user' role.
|
|
10
|
+
*/
|
|
11
|
+
declare function createUser(email: string, username: string, password: string): Promise<User>;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new user from an OAuth provider.
|
|
14
|
+
*/
|
|
15
|
+
declare function createOAuthUser(email: string, name: string, image?: string): Promise<User>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a user by ID.
|
|
18
|
+
*/
|
|
19
|
+
declare function getUserById(userId: string): Promise<User | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Decrypts and returns the user's recovery code.
|
|
22
|
+
*/
|
|
23
|
+
declare function getUserRecoverCode(userId: string): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Generates and sets a new recovery code for the user.
|
|
26
|
+
*/
|
|
27
|
+
declare function resetUserRecoveryCode(userId: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Updates the user's password.
|
|
30
|
+
*/
|
|
31
|
+
declare function updateUserPassword(userId: string, password: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Updates the user's name.
|
|
34
|
+
*/
|
|
35
|
+
declare function updateUserName(userId: string, name: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Updates the user's image.
|
|
38
|
+
*/
|
|
39
|
+
declare function updateUserAwatar(userId: string, image: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Updates the user's email and marks it as verified.
|
|
42
|
+
*/
|
|
43
|
+
declare function updateUserEmailAndSetEmailAsVerified(userId: string, email: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Sets the user as email verified if the provided email matches.
|
|
46
|
+
*/
|
|
47
|
+
declare function setUserAsEmailVerifiedIfEmailMatches(userId: string, email: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Returns the user's password hash.
|
|
50
|
+
*/
|
|
51
|
+
declare function getUserPasswordHash(userId: string): Promise<string | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns a user by email.
|
|
54
|
+
*/
|
|
55
|
+
declare function getUserFromEmail(email: string): Promise<User | null>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createOAuthUser, createUser, getUserById, getUserFromEmail, getUserPasswordHash, getUserRecoverCode, resetUserRecoveryCode, setUserAsEmailVerifiedIfEmailMatches, updateUserAwatar, updateUserEmailAndSetEmailAsVerified, updateUserName, updateUserPassword, verifyUsernameInput };
|
|
58
|
+
//# sourceMappingURL=user.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.d.mts","names":[],"sources":["../../../src/server/auth/user.ts"],"mappings":";;;;;AAiBA;iBAAsB,mBAAA,CAAoB,QAAA,WAAmB,OAAA;;;;iBASvC,UAAA,CACpB,KAAA,UACA,QAAA,UACA,QAAA,WACC,OAAA,CAAQ,IAAA;;;;iBA+CW,eAAA,CACpB,KAAA,UACA,IAAA,UACA,KAAA,YACC,OAAA,CAAQ,IAAA;;;;iBAyCW,WAAA,CAAY,MAAA,WAAiB,OAAA,CAAQ,IAAA;;;AA7C3D;iBA2DsB,kBAAA,CAAmB,MAAA,WAAiB,OAAA;;;;iBAkBpC,qBAAA,CAAsB,MAAA,WAAiB,OAAA;;;;iBAuBvC,kBAAA,CACpB,MAAA,UACA,QAAA,WACC,OAAA;;AA1DH;;iBAwEsB,cAAA,CACpB,MAAA,UACA,IAAA,WACC,OAAA;;;;iBAWmB,gBAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;AA3EH;iBAuFsB,oCAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;;iBAamB,oCAAA,CACpB,MAAA,UACA,KAAA,WACC,OAAA;;;;iBAemB,mBAAA,CACpB,MAAA,WACC,OAAA;AAlFH;;;AAAA,iBAoGsB,gBAAA,CAAiB,KAAA,WAAgB,OAAA,CAAQ,IAAA"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { db } from "../database/inject.mjs";
|
|
4
|
+
import { rolesTable, userTable, usersToRolesTable } from "../database/schema.mjs";
|
|
5
|
+
import { sendRecoveryCode } from "../emails/index.mjs";
|
|
6
|
+
import { hashPassword } from "./password.mjs";
|
|
7
|
+
import { generateRandomRecoveryCode } from "../../core/auth/utils/encode.mjs";
|
|
8
|
+
import { decryptToString, encryptString } from "../../core/auth/utils/encryption.mjs";
|
|
9
|
+
import { and, eq } from "drizzle-orm";
|
|
10
|
+
|
|
11
|
+
//#region src/server/auth/user.ts
|
|
12
|
+
/**
|
|
13
|
+
* Validates the username input.
|
|
14
|
+
*/
|
|
15
|
+
async function verifyUsernameInput(username) {
|
|
16
|
+
return username.length > 3 && username.length < 32 && username.trim() === username;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new user with an initial recovery code and default 'user' role.
|
|
20
|
+
*/
|
|
21
|
+
async function createUser(email, username, password) {
|
|
22
|
+
const passwordHash = await hashPassword(password);
|
|
23
|
+
const recoveryCode = generateRandomRecoveryCode();
|
|
24
|
+
const encryptedRecoveryCode = encryptString(recoveryCode);
|
|
25
|
+
return await db.transaction(async (tx) => {
|
|
26
|
+
const [row] = await tx.insert(userTable).values({
|
|
27
|
+
email,
|
|
28
|
+
name: username,
|
|
29
|
+
password: passwordHash,
|
|
30
|
+
recovery_code: Buffer.from(encryptedRecoveryCode)
|
|
31
|
+
}).returning();
|
|
32
|
+
if (!row) throw new Error("Failed to create user");
|
|
33
|
+
let [role] = await tx.select().from(rolesTable).where(eq(rolesTable.name, "user"));
|
|
34
|
+
if (!role) [role] = await tx.insert(rolesTable).values({
|
|
35
|
+
name: "user",
|
|
36
|
+
description: "Default user role"
|
|
37
|
+
}).returning();
|
|
38
|
+
await tx.insert(usersToRolesTable).values({
|
|
39
|
+
userId: row.id,
|
|
40
|
+
roleId: role.id
|
|
41
|
+
});
|
|
42
|
+
await /* @__PURE__ */ sendRecoveryCode(row.email, recoveryCode);
|
|
43
|
+
return row;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new user from an OAuth provider.
|
|
48
|
+
*/
|
|
49
|
+
async function createOAuthUser(email, name, image) {
|
|
50
|
+
const encryptedRecoveryCode = encryptString(generateRandomRecoveryCode());
|
|
51
|
+
return await db.transaction(async (tx) => {
|
|
52
|
+
const [row] = await tx.insert(userTable).values({
|
|
53
|
+
email,
|
|
54
|
+
name,
|
|
55
|
+
image,
|
|
56
|
+
emailVerifiedAt: /* @__PURE__ */ new Date(),
|
|
57
|
+
recovery_code: Buffer.from(encryptedRecoveryCode)
|
|
58
|
+
}).returning();
|
|
59
|
+
let [role] = await tx.select().from(rolesTable).where(eq(rolesTable.name, "user"));
|
|
60
|
+
if (!role) [role] = await tx.insert(rolesTable).values({
|
|
61
|
+
name: "user",
|
|
62
|
+
description: "Default user role"
|
|
63
|
+
}).returning();
|
|
64
|
+
await tx.insert(usersToRolesTable).values({
|
|
65
|
+
userId: row.id,
|
|
66
|
+
roleId: role.id
|
|
67
|
+
});
|
|
68
|
+
return row;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns a user by ID.
|
|
73
|
+
*/
|
|
74
|
+
async function getUserById(userId) {
|
|
75
|
+
const [user] = await db.select().from(userTable).where(eq(userTable.id, userId));
|
|
76
|
+
if (!user) return null;
|
|
77
|
+
const { password, recovery_code, ...safeUser } = user;
|
|
78
|
+
return safeUser;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Decrypts and returns the user's recovery code.
|
|
82
|
+
*/
|
|
83
|
+
async function getUserRecoverCode(userId) {
|
|
84
|
+
const [user] = await db.select({ recovery_code: userTable.recovery_code }).from(userTable).where(eq(userTable.id, userId));
|
|
85
|
+
if (!user || !user.recovery_code) throw new Error("Recovery code not found for user");
|
|
86
|
+
return decryptToString(user.recovery_code);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generates and sets a new recovery code for the user.
|
|
90
|
+
*/
|
|
91
|
+
async function resetUserRecoveryCode(userId) {
|
|
92
|
+
const recoveryCode = generateRandomRecoveryCode();
|
|
93
|
+
const encrypted = encryptString(recoveryCode);
|
|
94
|
+
const [currentUser] = await db.update(userTable).set({ recovery_code: Buffer.from(encrypted) }).where(eq(userTable.id, userId)).returning();
|
|
95
|
+
if (!currentUser) throw new Error("User not found");
|
|
96
|
+
await /* @__PURE__ */ sendRecoveryCode(currentUser.email, recoveryCode);
|
|
97
|
+
return recoveryCode;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Updates the user's password.
|
|
101
|
+
*/
|
|
102
|
+
async function updateUserPassword(userId, password) {
|
|
103
|
+
const passwordHash = await hashPassword(password);
|
|
104
|
+
await db.update(userTable).set({ password: passwordHash }).where(eq(userTable.id, userId));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Updates the user's name.
|
|
108
|
+
*/
|
|
109
|
+
async function updateUserName(userId, name) {
|
|
110
|
+
await db.update(userTable).set({ name }).where(eq(userTable.id, userId));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Updates the user's image.
|
|
114
|
+
*/
|
|
115
|
+
async function updateUserAwatar(userId, image) {
|
|
116
|
+
await db.update(userTable).set({ image }).where(eq(userTable.id, userId));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Updates the user's email and marks it as verified.
|
|
120
|
+
*/
|
|
121
|
+
async function updateUserEmailAndSetEmailAsVerified(userId, email) {
|
|
122
|
+
await db.update(userTable).set({
|
|
123
|
+
email,
|
|
124
|
+
emailVerifiedAt: /* @__PURE__ */ new Date()
|
|
125
|
+
}).where(eq(userTable.id, userId));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Sets the user as email verified if the provided email matches.
|
|
129
|
+
*/
|
|
130
|
+
async function setUserAsEmailVerifiedIfEmailMatches(userId, email) {
|
|
131
|
+
return (await db.update(userTable).set({ emailVerifiedAt: /* @__PURE__ */ new Date() }).where(and(eq(userTable.id, userId), eq(userTable.email, email))).returning({ id: userTable.id })).length > 0;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Returns the user's password hash.
|
|
135
|
+
*/
|
|
136
|
+
async function getUserPasswordHash(userId) {
|
|
137
|
+
const [user] = await db.select({ password: userTable.password }).from(userTable).where(eq(userTable.id, userId));
|
|
138
|
+
if (!user) throw new Error("User not found");
|
|
139
|
+
return user.password;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Returns a user by email.
|
|
143
|
+
*/
|
|
144
|
+
async function getUserFromEmail(email) {
|
|
145
|
+
const [user] = await db.select().from(userTable).where(eq(userTable.email, email));
|
|
146
|
+
if (!user) return null;
|
|
147
|
+
const { password, recovery_code, ...safeUser } = user;
|
|
148
|
+
return safeUser;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { createOAuthUser, createUser, getUserById, getUserFromEmail, getUserPasswordHash, getUserRecoverCode, resetUserRecoveryCode, setUserAsEmailVerifiedIfEmailMatches, updateUserAwatar, updateUserEmailAndSetEmailAsVerified, updateUserName, updateUserPassword, verifyUsernameInput };
|
|
153
|
+
//# sourceMappingURL=user.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.mjs","names":[],"sources":["../../../src/server/auth/user.ts"],"sourcesContent":["\"use server\";\n\nimport { and, eq } from \"drizzle-orm\";\nimport type { User } from \"../../core/auth/types\";\nimport { generateRandomRecoveryCode } from \"../../core/auth/utils/encode\";\nimport {\n decryptToString,\n encryptString,\n} from \"../../core/auth/utils/encryption\";\nimport { db } from \"../database/inject\";\nimport { rolesTable, usersToRolesTable, userTable } from \"../database/schema\";\nimport { sendRecoveryCode } from \"../emails\";\nimport { hashPassword } from \"./password\";\n\n/**\n * Validates the username input.\n */\nexport async function verifyUsernameInput(username: string): Promise<boolean> {\n return (\n username.length > 3 && username.length < 32 && username.trim() === username\n );\n}\n\n/**\n * Creates a new user with an initial recovery code and default 'user' role.\n */\nexport async function createUser(\n email: string,\n username: string,\n password: string,\n): Promise<User> {\n const passwordHash = await hashPassword(password);\n const recoveryCode = generateRandomRecoveryCode();\n const encryptedRecoveryCode = encryptString(recoveryCode);\n\n return await db.transaction(async (tx) => {\n const [row] = await tx\n .insert(userTable)\n .values({\n email: email,\n name: username,\n password: passwordHash,\n recovery_code: Buffer.from(encryptedRecoveryCode),\n })\n .returning();\n\n if (!row) {\n throw new Error(\"Failed to create user\");\n }\n\n // Assign default 'user' role\n let [role] = await tx\n .select()\n .from(rolesTable)\n .where(eq(rolesTable.name, \"user\"));\n\n if (!role) {\n [role] = await tx\n .insert(rolesTable)\n .values({ name: \"user\", description: \"Default user role\" })\n .returning();\n }\n\n await tx.insert(usersToRolesTable).values({\n userId: row.id,\n roleId: role.id,\n });\n\n await sendRecoveryCode(row.email, recoveryCode);\n\n return row;\n });\n}\n\n/**\n * Creates a new user from an OAuth provider.\n */\nexport async function createOAuthUser(\n email: string,\n name: string,\n image?: string,\n): Promise<User> {\n const recoveryCode = generateRandomRecoveryCode();\n const encryptedRecoveryCode = encryptString(recoveryCode);\n\n return await db.transaction(async (tx) => {\n const [row] = await tx\n .insert(userTable)\n .values({\n email: email,\n name: name,\n image: image,\n emailVerifiedAt: new Date(),\n recovery_code: Buffer.from(encryptedRecoveryCode),\n })\n .returning();\n\n // Assign default 'user' role\n let [role] = await tx\n .select()\n .from(rolesTable)\n .where(eq(rolesTable.name, \"user\"));\n\n if (!role) {\n [role] = await tx\n .insert(rolesTable)\n .values({ name: \"user\", description: \"Default user role\" })\n .returning();\n }\n\n await tx.insert(usersToRolesTable).values({\n userId: row.id,\n roleId: role.id,\n });\n\n return row;\n });\n}\n\n/**\n * Returns a user by ID.\n */\nexport async function getUserById(userId: string): Promise<User | null> {\n const [user] = await db\n .select()\n .from(userTable)\n .where(eq(userTable.id, userId));\n\n if (!user) return null;\n const { password, recovery_code, ...safeUser } = user;\n return safeUser as User;\n}\n\n/**\n * Decrypts and returns the user's recovery code.\n */\nexport async function getUserRecoverCode(userId: string): Promise<string> {\n const [user] = await db\n .select({\n recovery_code: userTable.recovery_code,\n })\n .from(userTable)\n .where(eq(userTable.id, userId));\n\n if (!user || !user.recovery_code) {\n throw new Error(\"Recovery code not found for user\");\n }\n\n return decryptToString(user.recovery_code);\n}\n\n/**\n * Generates and sets a new recovery code for the user.\n */\nexport async function resetUserRecoveryCode(userId: string): Promise<string> {\n const recoveryCode = generateRandomRecoveryCode();\n const encrypted = encryptString(recoveryCode);\n const [currentUser] = await db\n .update(userTable)\n .set({\n recovery_code: Buffer.from(encrypted),\n })\n .where(eq(userTable.id, userId))\n .returning();\n\n if (!currentUser) {\n throw new Error(\"User not found\");\n }\n\n await sendRecoveryCode(currentUser.email, recoveryCode);\n\n return recoveryCode;\n}\n\n/**\n * Updates the user's password.\n */\nexport async function updateUserPassword(\n userId: string,\n password: string,\n): Promise<void> {\n const passwordHash = await hashPassword(password);\n\n await db\n .update(userTable)\n .set({\n password: passwordHash,\n })\n .where(eq(userTable.id, userId));\n}\n\n/**\n * Updates the user's name.\n */\nexport async function updateUserName(\n userId: string,\n name: string,\n): Promise<void> {\n await db\n .update(userTable)\n .set({\n name: name,\n })\n .where(eq(userTable.id, userId));\n}\n/**\n * Updates the user's image.\n */\nexport async function updateUserAwatar(\n userId: string,\n image: string,\n): Promise<void> {\n await db\n .update(userTable)\n .set({\n image,\n })\n .where(eq(userTable.id, userId));\n}\n\n/**\n * Updates the user's email and marks it as verified.\n */\nexport async function updateUserEmailAndSetEmailAsVerified(\n userId: string,\n email: string,\n): Promise<void> {\n await db\n .update(userTable)\n .set({\n email: email,\n emailVerifiedAt: new Date(),\n })\n .where(eq(userTable.id, userId));\n}\n\n/**\n * Sets the user as email verified if the provided email matches.\n */\nexport async function setUserAsEmailVerifiedIfEmailMatches(\n userId: string,\n email: string,\n): Promise<boolean> {\n const result = await db\n .update(userTable)\n .set({\n emailVerifiedAt: new Date(),\n })\n .where(and(eq(userTable.id, userId), eq(userTable.email, email)))\n .returning({ id: userTable.id });\n\n return result.length > 0;\n}\n\n/**\n * Returns the user's password hash.\n */\nexport async function getUserPasswordHash(\n userId: string,\n): Promise<string | null> {\n const [user] = await db\n .select({\n password: userTable.password,\n })\n .from(userTable)\n .where(eq(userTable.id, userId));\n\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n return user.password;\n}\n\n/**\n * Returns a user by email.\n */\nexport async function getUserFromEmail(email: string): Promise<User | null> {\n const [user] = await db\n .select()\n .from(userTable)\n .where(eq(userTable.email, email));\n\n if (!user) return null;\n const { password, recovery_code, ...safeUser } = user;\n return safeUser as User;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/server/database/inject.ts
|
|
3
|
+
const globalForDb = globalThis;
|
|
4
|
+
function injectDb(db) {
|
|
5
|
+
if (globalForDb.__KRYO_DB__) return;
|
|
6
|
+
console.log("[Kryo:Core] >>> DATABASE INJECTED <<<");
|
|
7
|
+
globalForDb.__KRYO_DB__ = db;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Shared 'db' proxy.
|
|
11
|
+
* Resolves to globalThis.__KRYO_DB__ on every property access.
|
|
12
|
+
* Safe to import statically at top-level.
|
|
13
|
+
*/
|
|
14
|
+
const db = new Proxy({}, { get(_, prop) {
|
|
15
|
+
if (prop === "then") return void 0;
|
|
16
|
+
if (typeof prop === "symbol" || prop === "inspect" || prop === "toString") return globalForDb.__KRYO_DB__?.[prop];
|
|
17
|
+
const database = globalForDb.__KRYO_DB__;
|
|
18
|
+
if (!database) throw new Error(`[Kryo:Core] Database access error: tried to use "db.${String(prop)}" but database is not injected yet. Ensure you call "ensureSystemInitialized()" before using the database.`);
|
|
19
|
+
return database[prop];
|
|
20
|
+
} });
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.db = db;
|
|
24
|
+
exports.injectDb = injectDb;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { schema_d_exports } from "./schema.cjs";
|
|
2
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
3
|
+
|
|
4
|
+
//#region src/server/database/inject.d.ts
|
|
5
|
+
type KryoDatabase = NodePgDatabase<typeof schema_d_exports>;
|
|
6
|
+
declare function injectDb(db: KryoDatabase): void;
|
|
7
|
+
/**
|
|
8
|
+
* Shared 'db' proxy.
|
|
9
|
+
* Resolves to globalThis.__KRYO_DB__ on every property access.
|
|
10
|
+
* Safe to import statically at top-level.
|
|
11
|
+
*/
|
|
12
|
+
declare const db: KryoDatabase;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { KryoDatabase, db, injectDb };
|
|
15
|
+
//# sourceMappingURL=inject.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.d.cts","names":[],"sources":["../../../src/server/database/inject.ts"],"mappings":";;;;KAGY,YAAA,GAAe,cAAA,QAAsB,gBAAA;AAAA,iBAKjC,QAAA,CAAS,EAAA,EAAI,YAAA;AAL7B;;;;;AAAA,cAgBa,EAAA,EAAE,YAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { schema_d_exports } from "./schema.mjs";
|
|
2
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
3
|
+
|
|
4
|
+
//#region src/server/database/inject.d.ts
|
|
5
|
+
type KryoDatabase = NodePgDatabase<typeof schema_d_exports>;
|
|
6
|
+
declare function injectDb(db: KryoDatabase): void;
|
|
7
|
+
/**
|
|
8
|
+
* Shared 'db' proxy.
|
|
9
|
+
* Resolves to globalThis.__KRYO_DB__ on every property access.
|
|
10
|
+
* Safe to import statically at top-level.
|
|
11
|
+
*/
|
|
12
|
+
declare const db: KryoDatabase;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { KryoDatabase, db, injectDb };
|
|
15
|
+
//# sourceMappingURL=inject.d.mts.map
|