@nexpress/core 0.3.0 → 0.3.2

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 (76) hide show
  1. package/dist/auth.d.ts +26 -3
  2. package/dist/auth.js +5 -3
  3. package/dist/{can-FKIEV54H.js → can-UJ2NAOIR.js} +3 -3
  4. package/dist/{chunk-CHQJG4BB.js → chunk-2N53KKIL.js} +2 -2
  5. package/dist/{chunk-DWG3RZH2.js → chunk-2VZZ7M26.js} +2 -2
  6. package/dist/{chunk-4EPNN4XG.js → chunk-54KUQF3S.js} +2 -2
  7. package/dist/{chunk-QYP6E5FP.js → chunk-6UV2P5MW.js} +63 -50
  8. package/dist/chunk-6UV2P5MW.js.map +1 -0
  9. package/dist/{chunk-QSJIKNQJ.js → chunk-ANZBCOEH.js} +9 -9
  10. package/dist/{chunk-TD4KNSEP.js → chunk-C6HXDY46.js} +19 -19
  11. package/dist/{chunk-26RYBFTF.js → chunk-LMPYQLMH.js} +37 -5
  12. package/dist/chunk-LMPYQLMH.js.map +1 -0
  13. package/dist/{chunk-EVOBLRHW.js → chunk-M2FWG5OJ.js} +5 -5
  14. package/dist/chunk-P5WGQRSG.js +180 -0
  15. package/dist/chunk-P5WGQRSG.js.map +1 -0
  16. package/dist/{chunk-HM46WM45.js → chunk-RDTTK27V.js} +6 -6
  17. package/dist/{chunk-PQBJWZ7D.js → chunk-RJ76SKWQ.js} +4 -4
  18. package/dist/{chunk-74CGJJDY.js → chunk-RKM4GDWM.js} +1 -1
  19. package/dist/{chunk-CKT4QZDC.js → chunk-WJJ5MBH5.js} +5 -5
  20. package/dist/{chunk-DPRBHEHI.js → chunk-YOFCLTBR.js} +7 -4
  21. package/dist/chunk-YOFCLTBR.js.map +1 -0
  22. package/dist/{chunk-HTDDXBMY.js → chunk-ZA3IRJUQ.js} +81 -131
  23. package/dist/chunk-ZA3IRJUQ.js.map +1 -0
  24. package/dist/community.d.ts +1 -1
  25. package/dist/community.js +20 -19
  26. package/dist/{config-2Y2YGD25.js → config-O7QM2OQS.js} +8 -7
  27. package/dist/db-schema.d.ts +2 -2
  28. package/dist/db.d.ts +3 -3
  29. package/dist/db.js +1 -1
  30. package/dist/fields.d.ts +54 -0
  31. package/dist/fields.js +14 -0
  32. package/dist/{host-YSADWU7J.js → host-NI3LR774.js} +6 -5
  33. package/dist/i18n.d.ts +1 -1
  34. package/dist/i18n.js +1 -1
  35. package/dist/{index-9IhVtFfA.d.ts → index-CPp-zGgL.d.ts} +2 -2
  36. package/dist/{index-CXuqW_Gl.d.ts → index-DKoSaszT.d.ts} +1 -1
  37. package/dist/{index-ClcinJ29.d.ts → index-DymnczhP.d.ts} +1 -1
  38. package/dist/{index-7_PBSyOq.d.ts → index-UZn29S3i.d.ts} +1 -1
  39. package/dist/index.d.ts +102 -16
  40. package/dist/index.js +191 -79
  41. package/dist/index.js.map +1 -1
  42. package/dist/jobs.d.ts +2 -2
  43. package/dist/jobs.js +2 -2
  44. package/dist/media.d.ts +2 -2
  45. package/dist/media.js +2 -2
  46. package/dist/{mentions-NCQR4B72.js → mentions-U4JACYI6.js} +3 -3
  47. package/dist/{mutes-FJSSU2JP.js → mutes-MNQP6ACF.js} +3 -3
  48. package/dist/{scheduled-F77QCDOG.js → scheduled-BWJG35Z2.js} +7 -6
  49. package/dist/seo.d.ts +16 -3
  50. package/dist/seo.js +6 -5
  51. package/dist/{settings-JODDWMDB.js → settings-OZWM6L2K.js} +2 -2
  52. package/dist/settings-OZWM6L2K.js.map +1 -0
  53. package/dist/strings-4EWJYDOG.js +1 -1
  54. package/dist/{types-DI3gxsiY.d.ts → types-D31ppGJw.d.ts} +294 -2
  55. package/package.json +6 -1
  56. package/dist/chunk-26RYBFTF.js.map +0 -1
  57. package/dist/chunk-DPRBHEHI.js.map +0 -1
  58. package/dist/chunk-HTDDXBMY.js.map +0 -1
  59. package/dist/chunk-QYP6E5FP.js.map +0 -1
  60. /package/dist/{can-FKIEV54H.js.map → can-UJ2NAOIR.js.map} +0 -0
  61. /package/dist/{chunk-CHQJG4BB.js.map → chunk-2N53KKIL.js.map} +0 -0
  62. /package/dist/{chunk-DWG3RZH2.js.map → chunk-2VZZ7M26.js.map} +0 -0
  63. /package/dist/{chunk-4EPNN4XG.js.map → chunk-54KUQF3S.js.map} +0 -0
  64. /package/dist/{chunk-QSJIKNQJ.js.map → chunk-ANZBCOEH.js.map} +0 -0
  65. /package/dist/{chunk-TD4KNSEP.js.map → chunk-C6HXDY46.js.map} +0 -0
  66. /package/dist/{chunk-EVOBLRHW.js.map → chunk-M2FWG5OJ.js.map} +0 -0
  67. /package/dist/{chunk-HM46WM45.js.map → chunk-RDTTK27V.js.map} +0 -0
  68. /package/dist/{chunk-PQBJWZ7D.js.map → chunk-RJ76SKWQ.js.map} +0 -0
  69. /package/dist/{chunk-74CGJJDY.js.map → chunk-RKM4GDWM.js.map} +0 -0
  70. /package/dist/{chunk-CKT4QZDC.js.map → chunk-WJJ5MBH5.js.map} +0 -0
  71. /package/dist/{config-2Y2YGD25.js.map → config-O7QM2OQS.js.map} +0 -0
  72. /package/dist/{host-YSADWU7J.js.map → fields.js.map} +0 -0
  73. /package/dist/{mentions-NCQR4B72.js.map → host-NI3LR774.js.map} +0 -0
  74. /package/dist/{mutes-FJSSU2JP.js.map → mentions-U4JACYI6.js.map} +0 -0
  75. /package/dist/{scheduled-F77QCDOG.js.map → mutes-MNQP6ACF.js.map} +0 -0
  76. /package/dist/{settings-JODDWMDB.js.map → scheduled-BWJG35Z2.js.map} +0 -0
package/dist/auth.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { p as NpAccessFunction, n as NpUserRole, e as NpAuthUser } from './types-DI3gxsiY.js';
2
- export { F as NpPrincipal } from './types-DI3gxsiY.js';
1
+ import { p as NpAccessFunction, m as NpUserRole, e as NpAuthUser } from './types-D31ppGJw.js';
2
+ export { H as NpPrincipal } from './types-D31ppGJw.js';
3
3
  import { NodePgDatabase } from 'drizzle-orm/node-postgres';
4
4
  import { Options } from '@node-rs/argon2';
5
5
 
@@ -72,6 +72,29 @@ declare function verifyToken(token: string, secret: string, expectedUse?: NpToke
72
72
  */
73
73
  declare function isTokenVerificationError(err: unknown): boolean;
74
74
 
75
+ /**
76
+ * Minimal public projection of a user row — `id` + `name` + `email`.
77
+ * Themes / plugins reach for this when they need to display a byline
78
+ * (post.author → user) without pulling in session machinery. Password
79
+ * hash + tokenVersion + reset state stay private to the auth module.
80
+ */
81
+ interface NpUserBasic {
82
+ id: string;
83
+ name: string;
84
+ email: string;
85
+ }
86
+ /**
87
+ * Look up a user by id. Returns `null` when the id doesn't exist
88
+ * (caller handles missing-author UI). UUID validation lives at the
89
+ * caller — Postgres rejects malformed ids inside `eq()` and the
90
+ * surfacing error is already informative.
91
+ *
92
+ * This is the supported entry point for theme code that needs to
93
+ * render a byline from `posts.author: relationTo("users")`. Direct
94
+ * drizzle reads against `np_users` are private to the framework.
95
+ */
96
+ declare function getUserById(id: string): Promise<NpUserBasic | null>;
97
+
75
98
  declare const ARGON2_OPTIONS: Options;
76
99
  declare function hashPassword(password: string): Promise<string>;
77
100
  declare function verifyPassword(passwordHash: string, password: string): Promise<boolean>;
@@ -637,4 +660,4 @@ interface NpConsumeMemberResetResult {
637
660
  }
638
661
  declare function consumeMemberPasswordReset(db: NodePgDatabase<Record<string, unknown>>, token: string, newPassword: string): Promise<NpConsumeMemberResetResult>;
639
662
 
640
- export { ARGON2_OPTIONS, type ArcticLikeProvider, type ArcticLikeTokens, type FromArcticOptions, type IssuedOAuthState, type NpCapability, type NpConsumeMemberEmailVerifyResult, type NpConsumeMemberResetResult, type NpConsumeResetTokenOptions, type NpConsumeResetTokenResult, type NpCreateResetTokenOptions, type NpIssuedMemberToken, type NpIssuedResetToken, type NpMemberAuthRow, type NpMemberIdentityRow, type NpMemberResetRequestResult, type NpMemberTokenPayload, type NpPasswordResetPurpose, type NpResetRequestResult, type NpTokenPayload, type NpUserIdentityRow, type OAuthAuthorizeParams, type OAuthExchangeParams, type OAuthProfile, type OAuthProvider, type OAuthStatePayload, type ResolveMemberOAuthLoginInput, type ResolveMemberOAuthLoginResult, type ResolveOAuthLoginInput, type ResolveOAuthLoginResult, type ResolvedOAuthMember, type ResolvedOAuthUser, type VerifyOAuthStateResult, authenticated, can, consumeMemberEmailVerifyToken, consumeMemberPasswordReset, consumePasswordResetToken, createMemberEmailVerifyToken, createPasswordResetToken, fromArctic, getMemberFromTokenPayload, getOAuthProvider, hashPassword, invalidateAllMemberSessions, invalidateAllSessions, isAdmin, isEditorOrAbove, isOwnerOrAdmin, isTokenVerificationError, issueOAuthState, listMemberIdentities, listOAuthProviders, listUserIdentities, registerOAuthProvider, requestMemberPasswordReset, requestPasswordReset, resetOAuthProviders, resolveMemberOAuthLogin, resolveOAuthLogin, revokeMemberIdentity, revokeUserIdentity, sha256, signMemberToken, signToken, verifyCsrf, verifyMemberToken, verifyOAuthState, verifyPassword, verifyToken, verifyTokenFull };
663
+ export { ARGON2_OPTIONS, type ArcticLikeProvider, type ArcticLikeTokens, type FromArcticOptions, type IssuedOAuthState, type NpCapability, type NpConsumeMemberEmailVerifyResult, type NpConsumeMemberResetResult, type NpConsumeResetTokenOptions, type NpConsumeResetTokenResult, type NpCreateResetTokenOptions, type NpIssuedMemberToken, type NpIssuedResetToken, type NpMemberAuthRow, type NpMemberIdentityRow, type NpMemberResetRequestResult, type NpMemberTokenPayload, type NpPasswordResetPurpose, type NpResetRequestResult, type NpTokenPayload, type NpUserBasic, type NpUserIdentityRow, type OAuthAuthorizeParams, type OAuthExchangeParams, type OAuthProfile, type OAuthProvider, type OAuthStatePayload, type ResolveMemberOAuthLoginInput, type ResolveMemberOAuthLoginResult, type ResolveOAuthLoginInput, type ResolveOAuthLoginResult, type ResolvedOAuthMember, type ResolvedOAuthUser, type VerifyOAuthStateResult, authenticated, can, consumeMemberEmailVerifyToken, consumeMemberPasswordReset, consumePasswordResetToken, createMemberEmailVerifyToken, createPasswordResetToken, fromArctic, getMemberFromTokenPayload, getOAuthProvider, getUserById, hashPassword, invalidateAllMemberSessions, invalidateAllSessions, isAdmin, isEditorOrAbove, isOwnerOrAdmin, isTokenVerificationError, issueOAuthState, listMemberIdentities, listOAuthProviders, listUserIdentities, registerOAuthProvider, requestMemberPasswordReset, requestPasswordReset, resetOAuthProviders, resolveMemberOAuthLogin, resolveOAuthLogin, revokeMemberIdentity, revokeUserIdentity, sha256, signMemberToken, signToken, verifyCsrf, verifyMemberToken, verifyOAuthState, verifyPassword, verifyToken, verifyTokenFull };
package/dist/auth.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  fromArctic,
10
10
  getMemberFromTokenPayload,
11
11
  getOAuthProvider,
12
+ getUserById,
12
13
  hashPassword,
13
14
  invalidateAllMemberSessions,
14
15
  invalidateAllSessions,
@@ -37,14 +38,14 @@ import {
37
38
  verifyPassword,
38
39
  verifyToken,
39
40
  verifyTokenFull
40
- } from "./chunk-QYP6E5FP.js";
41
+ } from "./chunk-6UV2P5MW.js";
41
42
  import {
42
43
  can
43
44
  } from "./chunk-EQ2Z3KMD.js";
44
45
  import "./chunk-ML2E3P3X.js";
45
- import "./chunk-74CGJJDY.js";
46
- import "./chunk-ZCINJSS4.js";
46
+ import "./chunk-RKM4GDWM.js";
47
47
  import "./chunk-SBCVAC2Z.js";
48
+ import "./chunk-ZCINJSS4.js";
48
49
  import "./chunk-OROPGO65.js";
49
50
  import "./chunk-NFHS7CFV.js";
50
51
  import "./chunk-XANPEOJC.js";
@@ -62,6 +63,7 @@ export {
62
63
  fromArctic,
63
64
  getMemberFromTokenPayload,
64
65
  getOAuthProvider,
66
+ getUserById,
65
67
  hashPassword,
66
68
  invalidateAllMemberSessions,
67
69
  invalidateAllSessions,
@@ -3,10 +3,10 @@ import {
3
3
  isMemberBanned,
4
4
  memberCan,
5
5
  withMemberWrite
6
- } from "./chunk-PQBJWZ7D.js";
6
+ } from "./chunk-RJ76SKWQ.js";
7
7
  import "./chunk-U4QCCLAW.js";
8
- import "./chunk-ZCINJSS4.js";
9
8
  import "./chunk-SBCVAC2Z.js";
9
+ import "./chunk-ZCINJSS4.js";
10
10
  import "./chunk-XANPEOJC.js";
11
11
  import "./chunk-X7K5F2UI.js";
12
12
  import "./chunk-PZ5AY32C.js";
@@ -16,4 +16,4 @@ export {
16
16
  memberCan,
17
17
  withMemberWrite
18
18
  };
19
- //# sourceMappingURL=can-FKIEV54H.js.map
19
+ //# sourceMappingURL=can-UJ2NAOIR.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getStorageAdapter
3
- } from "./chunk-DWG3RZH2.js";
3
+ } from "./chunk-2VZZ7M26.js";
4
4
  import {
5
5
  getDb
6
6
  } from "./chunk-XANPEOJC.js";
@@ -38,4 +38,4 @@ async function getMediaUrl(id, options = {}) {
38
38
  export {
39
39
  getMediaUrl
40
40
  };
41
- //# sourceMappingURL=chunk-CHQJG4BB.js.map
41
+ //# sourceMappingURL=chunk-2N53KKIL.js.map
@@ -170,7 +170,7 @@ async function uploadMedia(file, uploader, folderId) {
170
170
  return { id, status: "processing" };
171
171
  }
172
172
  async function assertMemberUploadQuota(memberId, txDb) {
173
- const { getCommunitySettings } = await import("./settings-JODDWMDB.js");
173
+ const { getCommunitySettings } = await import("./settings-OZWM6L2K.js");
174
174
  const { NpRateLimitError } = await import("./errors-5OS3S2J3.js");
175
175
  const settings = await getCommunitySettings();
176
176
  const { perDay, total } = settings.memberUploadQuota;
@@ -535,4 +535,4 @@ export {
535
535
  listMedia,
536
536
  cleanupDeletedMedia
537
537
  };
538
- //# sourceMappingURL=chunk-DWG3RZH2.js.map
538
+ //# sourceMappingURL=chunk-2VZZ7M26.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runHook
3
- } from "./chunk-HTDDXBMY.js";
3
+ } from "./chunk-ZA3IRJUQ.js";
4
4
  import {
5
5
  getAllCollectionSlugs,
6
6
  getCollectionConfig,
@@ -80,4 +80,4 @@ async function publishScheduledDocuments(atTime = /* @__PURE__ */ new Date()) {
80
80
  export {
81
81
  publishScheduledDocuments
82
82
  };
83
- //# sourceMappingURL=chunk-4EPNN4XG.js.map
83
+ //# sourceMappingURL=chunk-54KUQF3S.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ML2E3P3X.js";
4
4
  import {
5
5
  getCommunitySettings
6
- } from "./chunk-74CGJJDY.js";
6
+ } from "./chunk-RKM4GDWM.js";
7
7
  import {
8
8
  NpAuthError,
9
9
  NpForbiddenError,
@@ -65,6 +65,18 @@ function isTokenVerificationError(err) {
65
65
  return false;
66
66
  }
67
67
 
68
+ // src/auth/users.ts
69
+ import { eq } from "drizzle-orm";
70
+ async function getUserById(id) {
71
+ const db = getDb();
72
+ const [user] = await db.select({
73
+ id: npUsers.id,
74
+ name: npUsers.name,
75
+ email: npUsers.email
76
+ }).from(npUsers).where(eq(npUsers.id, id)).limit(1);
77
+ return user ?? null;
78
+ }
79
+
68
80
  // src/auth/password.ts
69
81
  import { hash, verify } from "@node-rs/argon2";
70
82
  var ARGON2_OPTIONS = {
@@ -122,7 +134,7 @@ function resetOAuthProviders() {
122
134
  }
123
135
 
124
136
  // src/auth/oauth-resolve.ts
125
- import { eq, and, sql } from "drizzle-orm";
137
+ import { eq as eq2, and, sql } from "drizzle-orm";
126
138
  var SYNTHETIC_EMAIL_SUFFIX = ".oauth.local";
127
139
  function syntheticEmail(provider, providerUserId) {
128
140
  return `${providerUserId}@${provider}${SYNTHETIC_EMAIL_SUFFIX}`;
@@ -142,13 +154,13 @@ async function resolveOAuthLogin(input) {
142
154
  identityId: npUserOAuthIdentities.id
143
155
  }).from(npUserOAuthIdentities).where(
144
156
  and(
145
- eq(npUserOAuthIdentities.provider, provider),
146
- eq(npUserOAuthIdentities.providerUserId, profile.providerUserId)
157
+ eq2(npUserOAuthIdentities.provider, provider),
158
+ eq2(npUserOAuthIdentities.providerUserId, profile.providerUserId)
147
159
  )
148
160
  ).limit(1);
149
161
  if (existingLink) {
150
162
  const metadata = mergeMetadata(profile);
151
- await db.update(npUserOAuthIdentities).set({ metadata, updatedAt: /* @__PURE__ */ new Date() }).where(eq(npUserOAuthIdentities.id, existingLink.identityId));
163
+ await db.update(npUserOAuthIdentities).set({ metadata, updatedAt: /* @__PURE__ */ new Date() }).where(eq2(npUserOAuthIdentities.id, existingLink.identityId));
152
164
  const user = await loadUser(db, existingLink.userId);
153
165
  return { user, created: false, linked: false };
154
166
  }
@@ -160,7 +172,7 @@ async function resolveOAuthLogin(input) {
160
172
  name: npUsers.name,
161
173
  role: npUsers.role,
162
174
  tokenVersion: npUsers.tokenVersion
163
- }).from(npUsers).where(eq(sql`lower(${npUsers.email})`, normalizedEmail)).limit(1);
175
+ }).from(npUsers).where(eq2(sql`lower(${npUsers.email})`, normalizedEmail)).limit(1);
164
176
  if (existingUser) {
165
177
  await db.insert(npUserOAuthIdentities).values({
166
178
  userId: existingUser.id,
@@ -211,7 +223,7 @@ async function loadUser(db, userId) {
211
223
  name: npUsers.name,
212
224
  role: npUsers.role,
213
225
  tokenVersion: npUsers.tokenVersion
214
- }).from(npUsers).where(eq(npUsers.id, userId)).limit(1);
226
+ }).from(npUsers).where(eq2(npUsers.id, userId)).limit(1);
215
227
  if (!row) {
216
228
  throw new Error(`User ${userId} referenced by oauth identity is missing`);
217
229
  }
@@ -219,7 +231,7 @@ async function loadUser(db, userId) {
219
231
  }
220
232
 
221
233
  // src/auth/oauth-resolve-member.ts
222
- import { and as and2, eq as eq2, sql as sql2 } from "drizzle-orm";
234
+ import { and as and2, eq as eq3, sql as sql2 } from "drizzle-orm";
223
235
  var SYNTHETIC_EMAIL_SUFFIX2 = ".oauth.local";
224
236
  var HANDLE_FALLBACK = "user";
225
237
  var HANDLE_RANDOM_SUFFIX_BYTES = 4;
@@ -254,7 +266,7 @@ async function loadMember(db, memberId) {
254
266
  displayName: npMembers.displayName,
255
267
  status: npMembers.status,
256
268
  tokenVersion: npMembers.tokenVersion
257
- }).from(npMembers).where(eq2(npMembers.id, memberId)).limit(1);
269
+ }).from(npMembers).where(eq3(npMembers.id, memberId)).limit(1);
258
270
  if (!row) {
259
271
  throw new Error(`Member ${memberId} referenced by oauth identity is missing`);
260
272
  }
@@ -265,12 +277,12 @@ async function resolveMemberOAuthLogin(input) {
265
277
  const { provider, profile } = input;
266
278
  const [existingLink] = await db.select({ memberId: npMemberIdentities.memberId, identityId: npMemberIdentities.id }).from(npMemberIdentities).where(
267
279
  and2(
268
- eq2(npMemberIdentities.provider, provider),
269
- eq2(npMemberIdentities.subject, profile.providerUserId)
280
+ eq3(npMemberIdentities.provider, provider),
281
+ eq3(npMemberIdentities.subject, profile.providerUserId)
270
282
  )
271
283
  ).limit(1);
272
284
  if (existingLink) {
273
- await db.update(npMemberIdentities).set({ metadata: mergeMetadata2(profile), updatedAt: /* @__PURE__ */ new Date() }).where(eq2(npMemberIdentities.id, existingLink.identityId));
285
+ await db.update(npMemberIdentities).set({ metadata: mergeMetadata2(profile), updatedAt: /* @__PURE__ */ new Date() }).where(eq3(npMemberIdentities.id, existingLink.identityId));
274
286
  const member = await loadMember(db, existingLink.memberId);
275
287
  return { member, created: false, linked: false };
276
288
  }
@@ -283,7 +295,7 @@ async function resolveMemberOAuthLogin(input) {
283
295
  displayName: npMembers.displayName,
284
296
  status: npMembers.status,
285
297
  tokenVersion: npMembers.tokenVersion
286
- }).from(npMembers).where(eq2(sql2`lower(${npMembers.email})`, normalizedEmail)).limit(1);
298
+ }).from(npMembers).where(eq3(sql2`lower(${npMembers.email})`, normalizedEmail)).limit(1);
287
299
  if (existingMember) {
288
300
  if (existingMember.status !== "active") {
289
301
  return { member: existingMember, created: false, linked: false };
@@ -409,7 +421,7 @@ function fromArctic(factory, opts) {
409
421
 
410
422
  // src/auth/session.ts
411
423
  import { webcrypto } from "crypto";
412
- import { eq as eq3, sql as sql3 } from "drizzle-orm";
424
+ import { eq as eq4, sql as sql3 } from "drizzle-orm";
413
425
  async function sha256(input) {
414
426
  const digest = await webcrypto.subtle.digest(
415
427
  "SHA-256",
@@ -428,7 +440,7 @@ async function verifyTokenFull(token, secret, db, expectedUse = "access") {
428
440
  name: npUsers.name,
429
441
  role: npUsers.role,
430
442
  tokenVersion: npUsers.tokenVersion
431
- }).from(npUsers).where(eq3(npUsers.id, payload.sub)).limit(1);
443
+ }).from(npUsers).where(eq4(npUsers.id, payload.sub)).limit(1);
432
444
  if (!user || user.tokenVersion !== payload.ver) {
433
445
  return null;
434
446
  }
@@ -438,47 +450,47 @@ async function invalidateAllSessions(userId, db) {
438
450
  await db.transaction(async (tx) => {
439
451
  await tx.update(npUsers).set({
440
452
  tokenVersion: sql3`${npUsers.tokenVersion} + 1`
441
- }).where(eq3(npUsers.id, userId));
442
- await tx.delete(npSessions).where(eq3(npSessions.userId, userId));
453
+ }).where(eq4(npUsers.id, userId));
454
+ await tx.delete(npSessions).where(eq4(npSessions.userId, userId));
443
455
  });
444
456
  }
445
457
 
446
458
  // src/auth/identities-admin.ts
447
- import { and as and3, desc, eq as eq4 } from "drizzle-orm";
459
+ import { and as and3, desc, eq as eq5 } from "drizzle-orm";
448
460
  async function assertUserExists(userId) {
449
461
  const db = getDb();
450
- const [row] = await db.select({ id: npUsers.id }).from(npUsers).where(eq4(npUsers.id, userId)).limit(1);
462
+ const [row] = await db.select({ id: npUsers.id }).from(npUsers).where(eq5(npUsers.id, userId)).limit(1);
451
463
  if (!row) throw new NpNotFoundError("user", userId);
452
464
  }
453
465
  async function assertMemberExists(memberId) {
454
466
  const db = getDb();
455
- const [row] = await db.select({ id: npMembers.id }).from(npMembers).where(eq4(npMembers.id, memberId)).limit(1);
467
+ const [row] = await db.select({ id: npMembers.id }).from(npMembers).where(eq5(npMembers.id, memberId)).limit(1);
456
468
  if (!row) throw new NpNotFoundError("member", memberId);
457
469
  }
458
470
  async function listUserIdentities(userId) {
459
471
  await assertUserExists(userId);
460
472
  const db = getDb();
461
- const rows = await db.select().from(npUserOAuthIdentities).where(eq4(npUserOAuthIdentities.userId, userId)).orderBy(desc(npUserOAuthIdentities.createdAt));
473
+ const rows = await db.select().from(npUserOAuthIdentities).where(eq5(npUserOAuthIdentities.userId, userId)).orderBy(desc(npUserOAuthIdentities.createdAt));
462
474
  return rows;
463
475
  }
464
476
  async function listMemberIdentities(memberId) {
465
477
  await assertMemberExists(memberId);
466
478
  const db = getDb();
467
- const rows = await db.select().from(npMemberIdentities).where(eq4(npMemberIdentities.memberId, memberId)).orderBy(desc(npMemberIdentities.createdAt));
479
+ const rows = await db.select().from(npMemberIdentities).where(eq5(npMemberIdentities.memberId, memberId)).orderBy(desc(npMemberIdentities.createdAt));
468
480
  return rows;
469
481
  }
470
482
  async function revokeUserIdentity(userId, identityId, actor) {
471
483
  const db = getDb();
472
484
  const [existing] = await db.select().from(npUserOAuthIdentities).where(
473
485
  and3(
474
- eq4(npUserOAuthIdentities.id, identityId),
475
- eq4(npUserOAuthIdentities.userId, userId)
486
+ eq5(npUserOAuthIdentities.id, identityId),
487
+ eq5(npUserOAuthIdentities.userId, userId)
476
488
  )
477
489
  ).limit(1);
478
490
  if (!existing) {
479
491
  throw new NpNotFoundError("identity", identityId);
480
492
  }
481
- const deleted = await db.delete(npUserOAuthIdentities).where(eq4(npUserOAuthIdentities.id, identityId)).returning({ id: npUserOAuthIdentities.id });
493
+ const deleted = await db.delete(npUserOAuthIdentities).where(eq5(npUserOAuthIdentities.id, identityId)).returning({ id: npUserOAuthIdentities.id });
482
494
  if (deleted.length === 0) return;
483
495
  await recordAuditEvent({
484
496
  actor: { kind: "staff", userId: actor.staffUserId },
@@ -496,12 +508,12 @@ async function revokeMemberIdentity(memberId, identityId, actor) {
496
508
  const db = getDb();
497
509
  const [existing] = await db.select().from(npMemberIdentities).where(
498
510
  and3(
499
- eq4(npMemberIdentities.id, identityId),
500
- eq4(npMemberIdentities.memberId, memberId)
511
+ eq5(npMemberIdentities.id, identityId),
512
+ eq5(npMemberIdentities.memberId, memberId)
501
513
  )
502
514
  ).limit(1);
503
515
  if (!existing) throw new NpNotFoundError("identity", identityId);
504
- const deleted = await db.delete(npMemberIdentities).where(eq4(npMemberIdentities.id, identityId)).returning({ id: npMemberIdentities.id });
516
+ const deleted = await db.delete(npMemberIdentities).where(eq5(npMemberIdentities.id, identityId)).returning({ id: npMemberIdentities.id });
505
517
  if (deleted.length === 0) return;
506
518
  await recordAuditEvent({
507
519
  actor: { kind: "staff", userId: actor.staffUserId },
@@ -518,7 +530,7 @@ async function revokeMemberIdentity(memberId, identityId, actor) {
518
530
 
519
531
  // src/auth/reset-token.ts
520
532
  import { randomBytes as randomBytes3 } from "crypto";
521
- import { and as and4, eq as eq5, gt, isNotNull, sql as sql4 } from "drizzle-orm";
533
+ import { and as and4, eq as eq6, gt, isNotNull, sql as sql4 } from "drizzle-orm";
522
534
  var MIN_PASSWORD_LENGTH = 8;
523
535
  function generateRawToken() {
524
536
  return randomBytes3(32).toString("hex");
@@ -532,7 +544,7 @@ async function createPasswordResetToken(db, options) {
532
544
  passwordResetExpiresAt: expiresAt,
533
545
  passwordResetPurpose: options.purpose,
534
546
  updatedAt: /* @__PURE__ */ new Date()
535
- }).where(eq5(npUsers.id, options.userId));
547
+ }).where(eq6(npUsers.id, options.userId));
536
548
  return { token, expiresAt, purpose: options.purpose };
537
549
  }
538
550
  async function requestPasswordReset(db, email, ttlMs) {
@@ -541,7 +553,7 @@ async function requestPasswordReset(db, email, ttlMs) {
541
553
  id: npUsers.id,
542
554
  email: npUsers.email,
543
555
  name: npUsers.name
544
- }).from(npUsers).where(eq5(npUsers.email, normalizedEmail)).limit(1);
556
+ }).from(npUsers).where(eq6(npUsers.email, normalizedEmail)).limit(1);
545
557
  if (!user) {
546
558
  return { userId: null, name: null, email: null, issued: null };
547
559
  }
@@ -574,7 +586,7 @@ async function consumePasswordResetToken(db, options) {
574
586
  purpose: npUsers.passwordResetPurpose
575
587
  }).from(npUsers).where(
576
588
  and4(
577
- eq5(npUsers.passwordResetTokenHash, tokenHash),
589
+ eq6(npUsers.passwordResetTokenHash, tokenHash),
578
590
  isNotNull(npUsers.passwordResetExpiresAt),
579
591
  gt(npUsers.passwordResetExpiresAt, now)
580
592
  )
@@ -595,8 +607,8 @@ async function consumePasswordResetToken(db, options) {
595
607
  lockUntil: null,
596
608
  tokenVersion: sql4`${npUsers.tokenVersion} + 1`,
597
609
  updatedAt: /* @__PURE__ */ new Date()
598
- }).where(eq5(npUsers.id, user.id));
599
- await tx.delete(npSessions).where(eq5(npSessions.userId, user.id));
610
+ }).where(eq6(npUsers.id, user.id));
611
+ await tx.delete(npSessions).where(eq6(npSessions.userId, user.id));
600
612
  });
601
613
  return {
602
614
  userId: user.id,
@@ -631,7 +643,7 @@ async function verifyMemberToken(token, secret, expectedUse) {
631
643
  }
632
644
 
633
645
  // src/auth/member-session.ts
634
- import { and as and5, eq as eq6, gt as gt2, sql as sql5 } from "drizzle-orm";
646
+ import { and as and5, eq as eq7, gt as gt2, sql as sql5 } from "drizzle-orm";
635
647
  async function getMemberFromTokenPayload(db, payload, accessToken) {
636
648
  const [row] = await db.select({
637
649
  id: npMembers.id,
@@ -640,7 +652,7 @@ async function getMemberFromTokenPayload(db, payload, accessToken) {
640
652
  displayName: npMembers.displayName,
641
653
  status: npMembers.status,
642
654
  tokenVersion: npMembers.tokenVersion
643
- }).from(npMembers).where(eq6(npMembers.id, payload.sub)).limit(1);
655
+ }).from(npMembers).where(eq7(npMembers.id, payload.sub)).limit(1);
644
656
  if (!row) return null;
645
657
  if (row.tokenVersion !== payload.ver) return null;
646
658
  if (accessToken) {
@@ -648,8 +660,8 @@ async function getMemberFromTokenPayload(db, payload, accessToken) {
648
660
  const now = /* @__PURE__ */ new Date();
649
661
  const [session] = await db.select({ id: npMemberSessions.id }).from(npMemberSessions).where(
650
662
  and5(
651
- eq6(npMemberSessions.memberId, row.id),
652
- eq6(npMemberSessions.tokenHash, tokenHash),
663
+ eq7(npMemberSessions.memberId, row.id),
664
+ eq7(npMemberSessions.tokenHash, tokenHash),
653
665
  gt2(npMemberSessions.expiresAt, now)
654
666
  )
655
667
  ).limit(1);
@@ -662,14 +674,14 @@ async function invalidateAllMemberSessions(db, memberId) {
662
674
  await tx.update(npMembers).set({
663
675
  tokenVersion: sql5`${npMembers.tokenVersion} + 1`,
664
676
  updatedAt: /* @__PURE__ */ new Date()
665
- }).where(eq6(npMembers.id, memberId));
666
- await tx.delete(npMemberSessions).where(eq6(npMemberSessions.memberId, memberId));
677
+ }).where(eq7(npMembers.id, memberId));
678
+ await tx.delete(npMemberSessions).where(eq7(npMemberSessions.memberId, memberId));
667
679
  });
668
680
  }
669
681
 
670
682
  // src/auth/member-credentials.ts
671
683
  import { randomBytes as randomBytes5 } from "crypto";
672
- import { and as and6, eq as eq7, gt as gt3, isNotNull as isNotNull2, sql as sql6 } from "drizzle-orm";
684
+ import { and as and6, eq as eq8, gt as gt3, isNotNull as isNotNull2, sql as sql6 } from "drizzle-orm";
673
685
  var MIN_PASSWORD_LENGTH2 = 8;
674
686
  function generateRawToken2() {
675
687
  return randomBytes5(32).toString("hex");
@@ -682,7 +694,7 @@ async function createMemberEmailVerifyToken(db, memberId, ttlMs) {
682
694
  emailVerifyTokenHash: tokenHash,
683
695
  emailVerifyExpiresAt: expiresAt,
684
696
  updatedAt: /* @__PURE__ */ new Date()
685
- }).where(eq7(npMembers.id, memberId));
697
+ }).where(eq8(npMembers.id, memberId));
686
698
  return { token, expiresAt };
687
699
  }
688
700
  async function consumeMemberEmailVerifyToken(db, token) {
@@ -700,7 +712,7 @@ async function consumeMemberEmailVerifyToken(db, token) {
700
712
  displayName: npMembers.displayName
701
713
  }).from(npMembers).where(
702
714
  and6(
703
- eq7(npMembers.emailVerifyTokenHash, tokenHash),
715
+ eq8(npMembers.emailVerifyTokenHash, tokenHash),
704
716
  isNotNull2(npMembers.emailVerifyExpiresAt),
705
717
  gt3(npMembers.emailVerifyExpiresAt, now)
706
718
  )
@@ -719,7 +731,7 @@ async function consumeMemberEmailVerifyToken(db, token) {
719
731
  emailVerifyTokenHash: null,
720
732
  emailVerifyExpiresAt: null,
721
733
  updatedAt: now
722
- }).where(eq7(npMembers.id, member.id));
734
+ }).where(eq8(npMembers.id, member.id));
723
735
  return {
724
736
  memberId: member.id,
725
737
  email: member.email,
@@ -734,7 +746,7 @@ async function requestMemberPasswordReset(db, email, ttlMs) {
734
746
  email: npMembers.email,
735
747
  displayName: npMembers.displayName,
736
748
  status: npMembers.status
737
- }).from(npMembers).where(eq7(npMembers.email, normalizedEmail)).limit(1);
749
+ }).from(npMembers).where(eq8(npMembers.email, normalizedEmail)).limit(1);
738
750
  if (!member || member.status === "deleted") {
739
751
  return { memberId: null, displayName: null, email: null, issued: null };
740
752
  }
@@ -745,7 +757,7 @@ async function requestMemberPasswordReset(db, email, ttlMs) {
745
757
  passwordResetTokenHash: tokenHash,
746
758
  passwordResetExpiresAt: expiresAt,
747
759
  updatedAt: /* @__PURE__ */ new Date()
748
- }).where(eq7(npMembers.id, member.id));
760
+ }).where(eq8(npMembers.id, member.id));
749
761
  return {
750
762
  memberId: member.id,
751
763
  displayName: member.displayName,
@@ -771,7 +783,7 @@ async function consumeMemberPasswordReset(db, token, newPassword) {
771
783
  const now = /* @__PURE__ */ new Date();
772
784
  const [member] = await db.select({ id: npMembers.id, email: npMembers.email }).from(npMembers).where(
773
785
  and6(
774
- eq7(npMembers.passwordResetTokenHash, tokenHash),
786
+ eq8(npMembers.passwordResetTokenHash, tokenHash),
775
787
  isNotNull2(npMembers.passwordResetExpiresAt),
776
788
  gt3(npMembers.passwordResetExpiresAt, now)
777
789
  )
@@ -796,8 +808,8 @@ async function consumeMemberPasswordReset(db, token, newPassword) {
796
808
  emailVerified: true,
797
809
  status: sql6`case when ${npMembers.status} = 'pending' then 'active' else ${npMembers.status} end`,
798
810
  updatedAt: /* @__PURE__ */ new Date()
799
- }).where(eq7(npMembers.id, member.id));
800
- await tx.delete(npMemberSessions).where(eq7(npMemberSessions.memberId, member.id));
811
+ }).where(eq8(npMembers.id, member.id));
812
+ await tx.delete(npMemberSessions).where(eq8(npMemberSessions.memberId, member.id));
801
813
  });
802
814
  return { memberId: member.id, email: member.email };
803
815
  }
@@ -810,6 +822,7 @@ export {
810
822
  signToken,
811
823
  verifyToken,
812
824
  isTokenVerificationError,
825
+ getUserById,
813
826
  ARGON2_OPTIONS,
814
827
  hashPassword,
815
828
  verifyPassword,
@@ -842,4 +855,4 @@ export {
842
855
  requestMemberPasswordReset,
843
856
  consumeMemberPasswordReset
844
857
  };
845
- //# sourceMappingURL=chunk-QYP6E5FP.js.map
858
+ //# sourceMappingURL=chunk-6UV2P5MW.js.map