@naisys/supervisor-database 3.0.0-beta.4 → 3.0.0-beta.5

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.
Files changed (30) hide show
  1. package/dist/dbConfig.js +2 -2
  2. package/dist/generated/prisma/browser.js +4 -4
  3. package/dist/generated/prisma/client.js +5 -5
  4. package/dist/generated/prisma/commonInputTypes.js +1 -1
  5. package/dist/generated/prisma/enums.js +12 -12
  6. package/dist/generated/prisma/internal/class.js +36 -28
  7. package/dist/generated/prisma/internal/prismaNamespace.js +42 -39
  8. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +34 -34
  9. package/dist/index.js +17 -2
  10. package/dist/migrationHelper.js +5 -5
  11. package/dist/prismaClient.js +12 -12
  12. package/dist/sessionService.js +135 -139
  13. package/package.json +6 -4
  14. package/dist/dbConfig.d.ts +0 -5
  15. package/dist/generated/prisma/browser.d.ts +0 -25
  16. package/dist/generated/prisma/client.d.ts +0 -44
  17. package/dist/generated/prisma/commonInputTypes.d.ts +0 -341
  18. package/dist/generated/prisma/enums.d.ts +0 -11
  19. package/dist/generated/prisma/internal/class.d.ts +0 -164
  20. package/dist/generated/prisma/internal/prismaNamespace.d.ts +0 -775
  21. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +0 -82
  22. package/dist/generated/prisma/models/SchemaVersion.d.ts +0 -984
  23. package/dist/generated/prisma/models/Session.d.ts +0 -1212
  24. package/dist/generated/prisma/models/User.d.ts +0 -1546
  25. package/dist/generated/prisma/models/UserPermission.d.ts +0 -1354
  26. package/dist/generated/prisma/models.d.ts +0 -6
  27. package/dist/index.d.ts +0 -8
  28. package/dist/migrationHelper.d.ts +0 -2
  29. package/dist/prismaClient.d.ts +0 -7
  30. package/dist/sessionService.d.ts +0 -88
@@ -14,195 +14,191 @@ let supervisorDb = null;
14
14
  * No-ops gracefully if NAISYS_FOLDER is unset or the database doesn't exist.
15
15
  */
16
16
  export async function createSupervisorDatabaseClient() {
17
- if (supervisorDb)
18
- return true;
19
- const dbPath = supervisorDbPath();
20
- if (!existsSync(dbPath))
21
- return false;
22
- supervisorDb = await createPrismaClient(dbPath);
23
- return true;
17
+ if (supervisorDb) return true;
18
+ const dbPath = supervisorDbPath();
19
+ if (!existsSync(dbPath)) return false;
20
+ supervisorDb = await createPrismaClient(dbPath);
21
+ return true;
24
22
  }
25
23
  /**
26
24
  * Find a session user by session token hash. Returns null if not found or expired.
27
25
  */
28
26
  export async function findSession(tokenHash) {
29
- if (!supervisorDb)
30
- return null;
31
- const session = await supervisorDb.session.findUnique({
32
- where: {
33
- tokenHash,
34
- expiresAt: { gt: new Date() },
35
- },
36
- include: { user: true },
37
- });
38
- if (!session)
39
- return null;
40
- return {
41
- userId: session.user.id,
42
- username: session.user.username,
43
- passwordHash: session.user.passwordHash,
44
- uuid: session.user.uuid,
45
- };
27
+ if (!supervisorDb) return null;
28
+ const session = await supervisorDb.session.findUnique({
29
+ where: {
30
+ tokenHash,
31
+ expiresAt: { gt: new Date() },
32
+ },
33
+ include: { user: true },
34
+ });
35
+ if (!session) return null;
36
+ return {
37
+ userId: session.user.id,
38
+ username: session.user.username,
39
+ passwordHash: session.user.passwordHash,
40
+ uuid: session.user.uuid,
41
+ };
46
42
  }
47
43
  /**
48
44
  * Look up a session user by username.
49
45
  */
50
46
  export async function lookupUsername(username) {
51
- if (!supervisorDb)
52
- return null;
53
- const user = await supervisorDb.user.findUnique({
54
- where: { username },
55
- });
56
- if (!user)
57
- return null;
58
- return {
59
- userId: user.id,
60
- username: user.username,
61
- passwordHash: user.passwordHash,
62
- uuid: user.uuid,
63
- };
47
+ if (!supervisorDb) return null;
48
+ const user = await supervisorDb.user.findUnique({
49
+ where: { username },
50
+ });
51
+ if (!user) return null;
52
+ return {
53
+ userId: user.id,
54
+ username: user.username,
55
+ passwordHash: user.passwordHash,
56
+ uuid: user.uuid,
57
+ };
64
58
  }
65
59
  /**
66
60
  * Find a supervisor user by API key. Returns null if not found or DB not initialized.
67
61
  */
68
62
  export async function findUserByApiKey(apiKey) {
69
- if (!supervisorDb)
70
- return null;
71
- const user = await supervisorDb.user.findUnique({
72
- where: { apiKey },
73
- select: { uuid: true, username: true },
74
- });
75
- return user;
63
+ if (!supervisorDb) return null;
64
+ const user = await supervisorDb.user.findUnique({
65
+ where: { apiKey },
66
+ select: { uuid: true, username: true },
67
+ });
68
+ return user;
76
69
  }
77
70
  /**
78
71
  * Authenticate a user by username/password and create a session.
79
72
  * Returns null if credentials are invalid or DB is not initialized.
80
73
  */
81
74
  export async function authenticateAndCreateSession(username, password) {
82
- const user = await lookupUsername(username);
83
- if (!user)
84
- return null;
85
- const valid = await bcrypt.compare(password, user.passwordHash);
86
- if (!valid)
87
- return null;
88
- const token = randomUUID();
89
- const tokenHash = hashToken(token);
90
- const expiresAt = new Date(Date.now() + SESSION_DURATION_MS);
91
- const dbUser = await supervisorDb.user.findUnique({
92
- where: { username },
93
- });
94
- await supervisorDb.session.create({
95
- data: {
96
- userId: dbUser.id,
97
- tokenHash,
98
- expiresAt,
99
- },
100
- });
101
- return { token, user, expiresAt };
75
+ const user = await lookupUsername(username);
76
+ if (!user) return null;
77
+ const valid = await bcrypt.compare(password, user.passwordHash);
78
+ if (!valid) return null;
79
+ const token = randomUUID();
80
+ const tokenHash = hashToken(token);
81
+ const expiresAt = new Date(Date.now() + SESSION_DURATION_MS);
82
+ const dbUser = await supervisorDb.user.findUnique({
83
+ where: { username },
84
+ });
85
+ await supervisorDb.session.create({
86
+ data: {
87
+ userId: dbUser.id,
88
+ tokenHash,
89
+ expiresAt,
90
+ },
91
+ });
92
+ return { token, user, expiresAt };
102
93
  }
103
94
  /**
104
95
  * Update a user's password hash. No-op if not initialized.
105
96
  */
106
97
  export async function updateUserPassword(username, passwordHash) {
107
- if (!supervisorDb)
108
- return;
109
- await supervisorDb.user.update({
110
- where: { username },
111
- data: { passwordHash },
112
- });
98
+ if (!supervisorDb) return;
99
+ await supervisorDb.user.update({
100
+ where: { username },
101
+ data: { passwordHash },
102
+ });
113
103
  }
114
104
  /**
115
105
  * Delete a session by token hash.
116
106
  */
117
107
  export async function deleteSession(tokenHash) {
118
- if (!supervisorDb)
119
- return;
120
- await supervisorDb.session.deleteMany({
121
- where: { tokenHash },
122
- });
108
+ if (!supervisorDb) return;
109
+ await supervisorDb.session.deleteMany({
110
+ where: { tokenHash },
111
+ });
123
112
  }
124
113
  /**
125
114
  * Ensure a "superadmin" user exists in the supervisor database.
126
115
  * If already exists, returns it as-is. Otherwise creates with generated credentials.
127
116
  */
128
117
  export async function ensureSuperAdmin() {
129
- if (!supervisorDb)
130
- throw new Error("Supervisor DB not initialized");
131
- const existing = await supervisorDb.user.findUnique({
132
- where: { username: SUPER_ADMIN_USERNAME },
133
- });
134
- if (existing) {
135
- return {
136
- created: false,
137
- user: {
138
- uuid: existing.uuid,
139
- username: existing.username,
140
- passwordHash: existing.passwordHash,
141
- apiKey: existing.apiKey,
142
- },
143
- };
144
- }
145
- const uuid = randomUUID();
146
- const password = randomUUID().slice(0, 8);
147
- const passwordHash = await bcrypt.hash(password, 10);
148
- const apiKey = randomBytes(32).toString("hex");
149
- const user = await supervisorDb.user.create({
150
- data: { uuid, username: SUPER_ADMIN_USERNAME, passwordHash, apiKey },
151
- });
152
- await supervisorDb.userPermission.create({
153
- data: { userId: user.id, permission: "supervisor_admin" },
154
- });
118
+ if (!supervisorDb) throw new Error("Supervisor DB not initialized");
119
+ const existing = await supervisorDb.user.findUnique({
120
+ where: { username: SUPER_ADMIN_USERNAME },
121
+ });
122
+ if (existing) {
155
123
  return {
156
- created: true,
157
- generatedPassword: password,
158
- user: { uuid, username: SUPER_ADMIN_USERNAME, passwordHash, apiKey },
124
+ created: false,
125
+ user: {
126
+ uuid: existing.uuid,
127
+ username: existing.username,
128
+ passwordHash: existing.passwordHash,
129
+ apiKey: existing.apiKey,
130
+ },
159
131
  };
132
+ }
133
+ const uuid = randomUUID();
134
+ const password = randomUUID().slice(0, 8);
135
+ const passwordHash = await bcrypt.hash(password, 10);
136
+ const apiKey = randomBytes(32).toString("hex");
137
+ const user = await supervisorDb.user.create({
138
+ data: { uuid, username: SUPER_ADMIN_USERNAME, passwordHash, apiKey },
139
+ });
140
+ await supervisorDb.userPermission.create({
141
+ data: { userId: user.id, permission: "supervisor_admin" },
142
+ });
143
+ return {
144
+ created: true,
145
+ generatedPassword: password,
146
+ user: { uuid, username: SUPER_ADMIN_USERNAME, passwordHash, apiKey },
147
+ };
160
148
  }
161
149
  /**
162
150
  * CLI entry point for --reset-password. Initializes supervisor sessions,
163
151
  * then runs the interactive password reset.
164
152
  */
165
153
  export async function handleResetPassword(options) {
166
- console.log(`NAISYS_FOLDER: ${process.env.NAISYS_FOLDER}`);
167
- await createSupervisorDatabaseClient();
168
- await resetPassword(options.findLocalUser, options.updateLocalPassword, options.username, options.password);
154
+ console.log(`NAISYS_FOLDER: ${process.env.NAISYS_FOLDER}`);
155
+ await createSupervisorDatabaseClient();
156
+ await resetPassword(
157
+ options.findLocalUser,
158
+ options.updateLocalPassword,
159
+ options.username,
160
+ options.password,
161
+ );
169
162
  }
170
163
  /**
171
164
  * CLI to reset a user's password. Updates both local DB (via callbacks) and
172
165
  * the supervisor DB. If username/password are provided, skips interactive
173
166
  * prompts.
174
167
  */
175
- export async function resetPassword(findLocalUser, updateLocalPassword, usernameArg, passwordArg) {
176
- let username;
177
- let password;
178
- if (usernameArg && passwordArg) {
179
- username = usernameArg;
180
- password = passwordArg;
181
- }
182
- else {
183
- const rl = readline.createInterface({
184
- input: process.stdin,
185
- output: process.stdout,
186
- });
187
- try {
188
- username = usernameArg || (await rl.question("Username: "));
189
- password = passwordArg || (await rl.question("New password: "));
190
- }
191
- finally {
192
- rl.close();
193
- }
194
- }
195
- const user = await findLocalUser(username);
196
- if (!user) {
197
- console.error(`User '${username}' not found.`);
198
- process.exit(1);
199
- }
200
- if (password.length < 6) {
201
- console.error("Password must be at least 6 characters.");
202
- process.exit(1);
168
+ export async function resetPassword(
169
+ findLocalUser,
170
+ updateLocalPassword,
171
+ usernameArg,
172
+ passwordArg,
173
+ ) {
174
+ let username;
175
+ let password;
176
+ if (usernameArg && passwordArg) {
177
+ username = usernameArg;
178
+ password = passwordArg;
179
+ } else {
180
+ const rl = readline.createInterface({
181
+ input: process.stdin,
182
+ output: process.stdout,
183
+ });
184
+ try {
185
+ username = usernameArg || (await rl.question("Username: "));
186
+ password = passwordArg || (await rl.question("New password: "));
187
+ } finally {
188
+ rl.close();
203
189
  }
204
- const hash = await bcrypt.hash(password, 10);
205
- await updateLocalPassword(user.id, hash);
206
- await updateUserPassword(username, hash);
207
- console.log(`Password reset for '${username}'.`);
190
+ }
191
+ const user = await findLocalUser(username);
192
+ if (!user) {
193
+ console.error(`User '${username}' not found.`);
194
+ process.exit(1);
195
+ }
196
+ if (password.length < 6) {
197
+ console.error("Password must be at least 6 characters.");
198
+ process.exit(1);
199
+ }
200
+ const hash = await bcrypt.hash(password, 10);
201
+ await updateLocalPassword(user.id, hash);
202
+ await updateUserPassword(username, hash);
203
+ console.log(`Password reset for '${username}'.`);
208
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naisys/supervisor-database",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-beta.5",
4
4
  "type": "module",
5
5
  "description": "[internal] Supervisor database schema and Prisma client for NAISYS",
6
6
  "files": [
@@ -8,7 +8,9 @@
8
8
  "prisma.config.ts",
9
9
  "prisma/schema.prisma",
10
10
  "prisma/migrations",
11
- "!dist/**/*.map"
11
+ "!dist/**/*.map",
12
+ "!dist/**/*.d.ts",
13
+ "!dist/**/*.d.ts.map"
12
14
  ],
13
15
  "scripts": {
14
16
  "clean": "rimraf dist",
@@ -24,8 +26,8 @@
24
26
  "typescript": "^5.9.3"
25
27
  },
26
28
  "dependencies": {
27
- "@naisys/common": "3.0.0-beta.4",
28
- "@naisys/common-node": "3.0.0-beta.4",
29
+ "@naisys/common": "3.0.0-beta.5",
30
+ "@naisys/common-node": "3.0.0-beta.5",
29
31
  "bcryptjs": "^3.0.2",
30
32
  "@prisma/adapter-better-sqlite3": "^7.5.0",
31
33
  "@prisma/client": "^7.5.0",
@@ -1,5 +0,0 @@
1
- export declare function supervisorDbPath(): string;
2
- export declare function supervisorDbUrl(): string;
3
- /** We run migration scripts if this is greater than what's in the schema_version table */
4
- export declare const SUPERVISOR_DB_VERSION = 8;
5
- //# sourceMappingURL=dbConfig.d.ts.map
@@ -1,25 +0,0 @@
1
- import * as Prisma from './internal/prismaNamespaceBrowser.js';
2
- export { Prisma };
3
- export * as $Enums from './enums.js';
4
- export * from './enums.js';
5
- /**
6
- * Model User
7
- *
8
- */
9
- export type User = Prisma.UserModel;
10
- /**
11
- * Model Session
12
- *
13
- */
14
- export type Session = Prisma.SessionModel;
15
- /**
16
- * Model UserPermission
17
- *
18
- */
19
- export type UserPermission = Prisma.UserPermissionModel;
20
- /**
21
- * Model SchemaVersion
22
- *
23
- */
24
- export type SchemaVersion = Prisma.SchemaVersionModel;
25
- //# sourceMappingURL=browser.d.ts.map
@@ -1,44 +0,0 @@
1
- import * as runtime from "@prisma/client/runtime/client";
2
- import * as $Class from "./internal/class.js";
3
- import * as Prisma from "./internal/prismaNamespace.js";
4
- export * as $Enums from './enums.js';
5
- export * from "./enums.js";
6
- /**
7
- * ## Prisma Client
8
- *
9
- * Type-safe database client for TypeScript
10
- * @example
11
- * ```
12
- * const prisma = new PrismaClient({
13
- * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
14
- * })
15
- * // Fetch zero or more Users
16
- * const users = await prisma.user.findMany()
17
- * ```
18
- *
19
- * Read more in our [docs](https://pris.ly/d/client).
20
- */
21
- export declare const PrismaClient: $Class.PrismaClientConstructor;
22
- export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>;
23
- export { Prisma };
24
- /**
25
- * Model User
26
- *
27
- */
28
- export type User = Prisma.UserModel;
29
- /**
30
- * Model Session
31
- *
32
- */
33
- export type Session = Prisma.SessionModel;
34
- /**
35
- * Model UserPermission
36
- *
37
- */
38
- export type UserPermission = Prisma.UserPermissionModel;
39
- /**
40
- * Model SchemaVersion
41
- *
42
- */
43
- export type SchemaVersion = Prisma.SchemaVersionModel;
44
- //# sourceMappingURL=client.d.ts.map