@meshscale/db 0.1.0

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.
@@ -0,0 +1,521 @@
1
+ import { relations } from "drizzle-orm";
2
+ import {
3
+ pgTable,
4
+ text,
5
+ timestamp,
6
+ boolean,
7
+ integer,
8
+ jsonb,
9
+ index,
10
+ uniqueIndex,
11
+ } from "drizzle-orm/pg-core";
12
+
13
+ export const user = pgTable("user", {
14
+ id: text("id").primaryKey(),
15
+ name: text("name").notNull(),
16
+ email: text("email").notNull().unique(),
17
+ emailVerified: boolean("email_verified").default(false).notNull(),
18
+ image: text("image"),
19
+ createdAt: timestamp("created_at").defaultNow().notNull(),
20
+ updatedAt: timestamp("updated_at")
21
+ .defaultNow()
22
+ .$onUpdate(() => /* @__PURE__ */ new Date())
23
+ .notNull(),
24
+ });
25
+
26
+ export const session = pgTable(
27
+ "session",
28
+ {
29
+ id: text("id").primaryKey(),
30
+ expiresAt: timestamp("expires_at").notNull(),
31
+ token: text("token").notNull().unique(),
32
+ createdAt: timestamp("created_at").defaultNow().notNull(),
33
+ updatedAt: timestamp("updated_at")
34
+ .$onUpdate(() => /* @__PURE__ */ new Date())
35
+ .notNull(),
36
+ ipAddress: text("ip_address"),
37
+ userAgent: text("user_agent"),
38
+ userId: text("user_id")
39
+ .notNull()
40
+ .references(() => user.id, { onDelete: "cascade" }),
41
+ activeOrganizationId: text("active_organization_id"),
42
+ },
43
+ (table) => [index("session_userId_idx").on(table.userId)],
44
+ );
45
+
46
+ export const account = pgTable(
47
+ "account",
48
+ {
49
+ id: text("id").primaryKey(),
50
+ accountId: text("account_id").notNull(),
51
+ providerId: text("provider_id").notNull(),
52
+ userId: text("user_id")
53
+ .notNull()
54
+ .references(() => user.id, { onDelete: "cascade" }),
55
+ accessToken: text("access_token"),
56
+ refreshToken: text("refresh_token"),
57
+ idToken: text("id_token"),
58
+ accessTokenExpiresAt: timestamp("access_token_expires_at"),
59
+ refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
60
+ scope: text("scope"),
61
+ password: text("password"),
62
+ createdAt: timestamp("created_at").defaultNow().notNull(),
63
+ updatedAt: timestamp("updated_at")
64
+ .$onUpdate(() => /* @__PURE__ */ new Date())
65
+ .notNull(),
66
+ },
67
+ (table) => [index("account_userId_idx").on(table.userId)],
68
+ );
69
+
70
+ export const verification = pgTable(
71
+ "verification",
72
+ {
73
+ id: text("id").primaryKey(),
74
+ identifier: text("identifier").notNull(),
75
+ value: text("value").notNull(),
76
+ expiresAt: timestamp("expires_at").notNull(),
77
+ createdAt: timestamp("created_at").defaultNow().notNull(),
78
+ updatedAt: timestamp("updated_at")
79
+ .defaultNow()
80
+ .$onUpdate(() => /* @__PURE__ */ new Date())
81
+ .notNull(),
82
+ },
83
+ (table) => [index("verification_identifier_idx").on(table.identifier)],
84
+ );
85
+
86
+ export const jwks = pgTable("jwks", {
87
+ id: text("id").primaryKey(),
88
+ publicKey: text("public_key").notNull(),
89
+ privateKey: text("private_key").notNull(),
90
+ createdAt: timestamp("created_at").notNull(),
91
+ expiresAt: timestamp("expires_at"),
92
+ alg: text("alg"),
93
+ crv: text("crv"),
94
+ });
95
+
96
+ export const organization = pgTable("organization", {
97
+ id: text("id").primaryKey(),
98
+ name: text("name").notNull(),
99
+ slug: text("slug").notNull().unique(),
100
+ logo: text("logo"),
101
+ createdAt: timestamp("created_at").notNull(),
102
+ metadata: text("metadata"),
103
+ });
104
+
105
+ export const member = pgTable(
106
+ "member",
107
+ {
108
+ id: text("id").primaryKey(),
109
+ organizationId: text("organization_id")
110
+ .notNull()
111
+ .references(() => organization.id, { onDelete: "cascade" }),
112
+ userId: text("user_id")
113
+ .notNull()
114
+ .references(() => user.id, { onDelete: "cascade" }),
115
+ role: text("role").default("member").notNull(),
116
+ createdAt: timestamp("created_at").notNull(),
117
+ },
118
+ (table) => [
119
+ index("member_organizationId_idx").on(table.organizationId),
120
+ index("member_userId_idx").on(table.userId),
121
+ ],
122
+ );
123
+
124
+ export const invitation = pgTable(
125
+ "invitation",
126
+ {
127
+ id: text("id").primaryKey(),
128
+ organizationId: text("organization_id")
129
+ .notNull()
130
+ .references(() => organization.id, { onDelete: "cascade" }),
131
+ email: text("email").notNull(),
132
+ role: text("role"),
133
+ status: text("status").default("pending").notNull(),
134
+ expiresAt: timestamp("expires_at").notNull(),
135
+ createdAt: timestamp("created_at").defaultNow().notNull(),
136
+ inviterId: text("inviter_id")
137
+ .notNull()
138
+ .references(() => user.id, { onDelete: "cascade" }),
139
+ },
140
+ (table) => [
141
+ index("invitation_organizationId_idx").on(table.organizationId),
142
+ index("invitation_email_idx").on(table.email),
143
+ ],
144
+ );
145
+
146
+ export const apikey = pgTable(
147
+ "apikey",
148
+ {
149
+ id: text("id").primaryKey(),
150
+ configId: text("config_id").default("default").notNull(),
151
+ name: text("name"),
152
+ start: text("start"),
153
+ referenceId: text("reference_id").notNull(),
154
+ prefix: text("prefix"),
155
+ key: text("key").notNull(),
156
+ refillInterval: integer("refill_interval"),
157
+ refillAmount: integer("refill_amount"),
158
+ lastRefillAt: timestamp("last_refill_at"),
159
+ enabled: boolean("enabled").default(true),
160
+ rateLimitEnabled: boolean("rate_limit_enabled").default(true),
161
+ rateLimitTimeWindow: integer("rate_limit_time_window").default(86400000),
162
+ rateLimitMax: integer("rate_limit_max").default(10),
163
+ requestCount: integer("request_count").default(0),
164
+ remaining: integer("remaining"),
165
+ lastRequest: timestamp("last_request"),
166
+ expiresAt: timestamp("expires_at"),
167
+ createdAt: timestamp("created_at").notNull(),
168
+ updatedAt: timestamp("updated_at").notNull(),
169
+ permissions: text("permissions"),
170
+ metadata: text("metadata"),
171
+ },
172
+ (table) => [
173
+ index("apikey_configId_idx").on(table.configId),
174
+ index("apikey_referenceId_idx").on(table.referenceId),
175
+ index("apikey_key_idx").on(table.key),
176
+ ],
177
+ );
178
+
179
+ export const oauthClient = pgTable(
180
+ "oauth_client",
181
+ {
182
+ id: text("id").primaryKey(),
183
+ clientId: text("client_id").notNull().unique(),
184
+ clientSecret: text("client_secret"),
185
+ clientDiscoveryId: text("client_discovery_id"),
186
+ disabled: boolean("disabled").default(false),
187
+ skipConsent: boolean("skip_consent"),
188
+ enableEndSession: boolean("enable_end_session"),
189
+ subjectType: text("subject_type"),
190
+ scopes: text("scopes").array(),
191
+ clientCredentialsScopes: text("client_credentials_scopes")
192
+ .array()
193
+ .default([]),
194
+ userId: text("user_id").references(() => user.id, { onDelete: "cascade" }),
195
+ createdAt: timestamp("created_at"),
196
+ updatedAt: timestamp("updated_at"),
197
+ name: text("name"),
198
+ uri: text("uri"),
199
+ icon: text("icon"),
200
+ contacts: text("contacts").array(),
201
+ tos: text("tos"),
202
+ policy: text("policy"),
203
+ softwareId: text("software_id"),
204
+ softwareVersion: text("software_version"),
205
+ softwareStatement: text("software_statement"),
206
+ redirectUris: text("redirect_uris").array().notNull(),
207
+ postLogoutRedirectUris: text("post_logout_redirect_uris").array(),
208
+ backchannelLogoutUri: text("backchannel_logout_uri"),
209
+ backchannelLogoutSessionRequired: boolean(
210
+ "backchannel_logout_session_required",
211
+ ),
212
+ tokenEndpointAuthMethod: text("token_endpoint_auth_method"),
213
+ applicationType: text("application_type"),
214
+ jwks: text("jwks"),
215
+ jwksUri: text("jwks_uri"),
216
+ grantTypes: text("grant_types").array(),
217
+ responseTypes: text("response_types").array(),
218
+ requirePKCE: boolean("require_pkce"),
219
+ dpopBoundAccessTokens: boolean("dpop_bound_access_tokens").default(false),
220
+ referenceId: text("reference_id"),
221
+ metadata: jsonb("metadata"),
222
+ },
223
+ (table) => [index("oauthClient_userId_idx").on(table.userId)],
224
+ );
225
+
226
+ export const oauthResource = pgTable("oauth_resource", {
227
+ id: text("id").primaryKey(),
228
+ identifier: text("identifier").notNull().unique(),
229
+ name: text("name").notNull(),
230
+ accessTokenTtl: integer("access_token_ttl"),
231
+ refreshTokenTtl: integer("refresh_token_ttl"),
232
+ signingAlgorithm: text("signing_algorithm"),
233
+ signingKeyId: text("signing_key_id"),
234
+ allowedScopes: text("allowed_scopes").array(),
235
+ customClaims: jsonb("custom_claims"),
236
+ dpopBoundAccessTokensRequired: boolean(
237
+ "dpop_bound_access_tokens_required",
238
+ ).default(false),
239
+ disabled: boolean("disabled").default(false),
240
+ createdAt: timestamp("created_at"),
241
+ updatedAt: timestamp("updated_at"),
242
+ policyVersion: integer("policy_version").default(1),
243
+ metadata: jsonb("metadata"),
244
+ });
245
+
246
+ export const oauthClientResource = pgTable(
247
+ "oauth_client_resource",
248
+ {
249
+ id: text("id").primaryKey(),
250
+ clientId: text("client_id")
251
+ .notNull()
252
+ .references(() => oauthClient.clientId, { onDelete: "cascade" }),
253
+ resourceId: text("resource_id")
254
+ .notNull()
255
+ .references(() => oauthResource.identifier, { onDelete: "cascade" }),
256
+ metadata: jsonb("metadata"),
257
+ createdAt: timestamp("created_at"),
258
+ },
259
+ (table) => [
260
+ uniqueIndex("oauthClientResource_clientId_resourceId_uidx").on(
261
+ table.clientId,
262
+ table.resourceId,
263
+ ),
264
+ index("oauthClientResource_clientId_idx").on(table.clientId),
265
+ index("oauthClientResource_resourceId_idx").on(table.resourceId),
266
+ ],
267
+ );
268
+
269
+ export const oauthRefreshToken = pgTable(
270
+ "oauth_refresh_token",
271
+ {
272
+ id: text("id").primaryKey(),
273
+ token: text("token").notNull().unique(),
274
+ clientId: text("client_id")
275
+ .notNull()
276
+ .references(() => oauthClient.clientId, { onDelete: "cascade" }),
277
+ sessionId: text("session_id").references(() => session.id, {
278
+ onDelete: "set null",
279
+ }),
280
+ userId: text("user_id")
281
+ .notNull()
282
+ .references(() => user.id, { onDelete: "cascade" }),
283
+ referenceId: text("reference_id"),
284
+ authorizationCodeId: text("authorization_code_id"),
285
+ resources: text("resources").array(),
286
+ requestedUserInfoClaims: text("requested_user_info_claims").array(),
287
+ expiresAt: timestamp("expires_at").notNull(),
288
+ createdAt: timestamp("created_at").notNull(),
289
+ revoked: timestamp("revoked"),
290
+ rotatedAt: timestamp("rotated_at"),
291
+ rotationReplayResponse: text("rotation_replay_response"),
292
+ rotationReplayExpiresAt: timestamp("rotation_replay_expires_at"),
293
+ authTime: timestamp("auth_time"),
294
+ confirmation: jsonb("confirmation"),
295
+ scopes: text("scopes").array().notNull(),
296
+ },
297
+ (table) => [
298
+ index("oauthRefreshToken_clientId_idx").on(table.clientId),
299
+ index("oauthRefreshToken_sessionId_idx").on(table.sessionId),
300
+ index("oauthRefreshToken_userId_idx").on(table.userId),
301
+ index("oauthRefreshToken_authorizationCodeId_idx").on(
302
+ table.authorizationCodeId,
303
+ ),
304
+ ],
305
+ );
306
+
307
+ export const oauthAccessToken = pgTable(
308
+ "oauth_access_token",
309
+ {
310
+ id: text("id").primaryKey(),
311
+ token: text("token").notNull().unique(),
312
+ clientId: text("client_id")
313
+ .notNull()
314
+ .references(() => oauthClient.clientId, { onDelete: "cascade" }),
315
+ sessionId: text("session_id").references(() => session.id, {
316
+ onDelete: "set null",
317
+ }),
318
+ userId: text("user_id").references(() => user.id, { onDelete: "cascade" }),
319
+ referenceId: text("reference_id"),
320
+ authorizationCodeId: text("authorization_code_id"),
321
+ resources: text("resources").array(),
322
+ requestedUserInfoClaims: text("requested_user_info_claims").array(),
323
+ refreshId: text("refresh_id").references(() => oauthRefreshToken.id, {
324
+ onDelete: "cascade",
325
+ }),
326
+ expiresAt: timestamp("expires_at").notNull(),
327
+ createdAt: timestamp("created_at").notNull(),
328
+ revoked: timestamp("revoked"),
329
+ confirmation: jsonb("confirmation"),
330
+ scopes: text("scopes").array().notNull(),
331
+ },
332
+ (table) => [
333
+ index("oauthAccessToken_clientId_idx").on(table.clientId),
334
+ index("oauthAccessToken_sessionId_idx").on(table.sessionId),
335
+ index("oauthAccessToken_userId_idx").on(table.userId),
336
+ index("oauthAccessToken_authorizationCodeId_idx").on(
337
+ table.authorizationCodeId,
338
+ ),
339
+ index("oauthAccessToken_refreshId_idx").on(table.refreshId),
340
+ ],
341
+ );
342
+
343
+ export const oauthConsent = pgTable(
344
+ "oauth_consent",
345
+ {
346
+ id: text("id").primaryKey(),
347
+ clientId: text("client_id")
348
+ .notNull()
349
+ .references(() => oauthClient.clientId, { onDelete: "cascade" }),
350
+ userId: text("user_id").references(() => user.id, { onDelete: "cascade" }),
351
+ referenceId: text("reference_id"),
352
+ resources: text("resources").array(),
353
+ requestedUserInfoClaims: text("requested_user_info_claims").array(),
354
+ scopes: text("scopes").array().notNull(),
355
+ createdAt: timestamp("created_at").notNull(),
356
+ updatedAt: timestamp("updated_at").notNull(),
357
+ },
358
+ (table) => [
359
+ index("oauthConsent_clientId_idx").on(table.clientId),
360
+ index("oauthConsent_userId_idx").on(table.userId),
361
+ ],
362
+ );
363
+
364
+ export const oauthClientAssertion = pgTable("oauth_client_assertion", {
365
+ id: text("id").primaryKey(),
366
+ expiresAt: timestamp("expires_at").notNull(),
367
+ });
368
+
369
+ export const userRelations = relations(user, ({ many }) => ({
370
+ sessions: many(session),
371
+ accounts: many(account),
372
+ members: many(member),
373
+ invitations: many(invitation),
374
+ oauthClients: many(oauthClient),
375
+ oauthRefreshTokens: many(oauthRefreshToken),
376
+ oauthAccessTokens: many(oauthAccessToken),
377
+ oauthConsents: many(oauthConsent),
378
+ }));
379
+
380
+ export const sessionRelations = relations(session, ({ one, many }) => ({
381
+ user: one(user, {
382
+ fields: [session.userId],
383
+ references: [user.id],
384
+ }),
385
+ oauthRefreshTokens: many(oauthRefreshToken),
386
+ oauthAccessTokens: many(oauthAccessToken),
387
+ }));
388
+
389
+ export const accountRelations = relations(account, ({ one }) => ({
390
+ user: one(user, {
391
+ fields: [account.userId],
392
+ references: [user.id],
393
+ }),
394
+ }));
395
+
396
+ export const organizationRelations = relations(organization, ({ many }) => ({
397
+ members: many(member),
398
+ invitations: many(invitation),
399
+ }));
400
+
401
+ export const memberRelations = relations(member, ({ one }) => ({
402
+ organization: one(organization, {
403
+ fields: [member.organizationId],
404
+ references: [organization.id],
405
+ }),
406
+ user: one(user, {
407
+ fields: [member.userId],
408
+ references: [user.id],
409
+ }),
410
+ }));
411
+
412
+ export const invitationRelations = relations(invitation, ({ one }) => ({
413
+ organization: one(organization, {
414
+ fields: [invitation.organizationId],
415
+ references: [organization.id],
416
+ }),
417
+ user: one(user, {
418
+ fields: [invitation.inviterId],
419
+ references: [user.id],
420
+ }),
421
+ }));
422
+
423
+ export const oauthClientRelations = relations(oauthClient, ({ one, many }) => ({
424
+ user: one(user, {
425
+ fields: [oauthClient.userId],
426
+ references: [user.id],
427
+ }),
428
+ oauthClientResources: many(oauthClientResource),
429
+ oauthRefreshTokens: many(oauthRefreshToken),
430
+ oauthAccessTokens: many(oauthAccessToken),
431
+ oauthConsents: many(oauthConsent),
432
+ }));
433
+
434
+ export const oauthResourceRelations = relations(oauthResource, ({ many }) => ({
435
+ oauthClientResources: many(oauthClientResource),
436
+ }));
437
+
438
+ export const oauthClientResourceRelations = relations(
439
+ oauthClientResource,
440
+ ({ one }) => ({
441
+ oauthClient: one(oauthClient, {
442
+ fields: [oauthClientResource.clientId],
443
+ references: [oauthClient.clientId],
444
+ }),
445
+ oauthResource: one(oauthResource, {
446
+ fields: [oauthClientResource.resourceId],
447
+ references: [oauthResource.identifier],
448
+ }),
449
+ }),
450
+ );
451
+
452
+ export const oauthRefreshTokenRelations = relations(
453
+ oauthRefreshToken,
454
+ ({ one, many }) => ({
455
+ oauthClient: one(oauthClient, {
456
+ fields: [oauthRefreshToken.clientId],
457
+ references: [oauthClient.clientId],
458
+ }),
459
+ session: one(session, {
460
+ fields: [oauthRefreshToken.sessionId],
461
+ references: [session.id],
462
+ }),
463
+ user: one(user, {
464
+ fields: [oauthRefreshToken.userId],
465
+ references: [user.id],
466
+ }),
467
+ oauthAccessTokens: many(oauthAccessToken),
468
+ }),
469
+ );
470
+
471
+ export const oauthAccessTokenRelations = relations(
472
+ oauthAccessToken,
473
+ ({ one }) => ({
474
+ oauthClient: one(oauthClient, {
475
+ fields: [oauthAccessToken.clientId],
476
+ references: [oauthClient.clientId],
477
+ }),
478
+ session: one(session, {
479
+ fields: [oauthAccessToken.sessionId],
480
+ references: [session.id],
481
+ }),
482
+ user: one(user, {
483
+ fields: [oauthAccessToken.userId],
484
+ references: [user.id],
485
+ }),
486
+ oauthRefreshToken: one(oauthRefreshToken, {
487
+ fields: [oauthAccessToken.refreshId],
488
+ references: [oauthRefreshToken.id],
489
+ }),
490
+ }),
491
+ );
492
+
493
+ export const oauthConsentRelations = relations(oauthConsent, ({ one }) => ({
494
+ oauthClient: one(oauthClient, {
495
+ fields: [oauthConsent.clientId],
496
+ references: [oauthClient.clientId],
497
+ }),
498
+ user: one(user, {
499
+ fields: [oauthConsent.userId],
500
+ references: [user.id],
501
+ }),
502
+ }));
503
+
504
+ export const schema = {
505
+ user,
506
+ session,
507
+ account,
508
+ verification,
509
+ jwks,
510
+ organization,
511
+ member,
512
+ invitation,
513
+ apikey,
514
+ oauthClient,
515
+ oauthResource,
516
+ oauthClientResource,
517
+ oauthRefreshToken,
518
+ oauthAccessToken,
519
+ oauthConsent,
520
+ oauthClientAssertion,
521
+ };
@@ -0,0 +1 @@
1
+ export * from './auth.js';
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+
7
+ "strict": true,
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "sourceMap": true,
11
+
12
+ "outDir": "dist",
13
+ "rootDir": "src",
14
+
15
+ "esModuleInterop": true,
16
+ "types": ["node"],
17
+ "skipLibCheck": true,
18
+ "paths": {
19
+ "@/*": ["./*"]
20
+ },
21
+ },
22
+ "include": ["src"]
23
+ }