@rovela-ai/sdk 0.2.0 → 0.3.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.
Files changed (178) hide show
  1. package/dist/admin/api/accept-invite.d.ts +65 -0
  2. package/dist/admin/api/accept-invite.d.ts.map +1 -0
  3. package/dist/admin/api/accept-invite.js +115 -0
  4. package/dist/admin/api/accept-invite.js.map +1 -0
  5. package/dist/admin/api/categories.d.ts.map +1 -1
  6. package/dist/admin/api/categories.js +21 -28
  7. package/dist/admin/api/categories.js.map +1 -1
  8. package/dist/admin/api/customers.d.ts.map +1 -1
  9. package/dist/admin/api/customers.js +17 -25
  10. package/dist/admin/api/customers.js.map +1 -1
  11. package/dist/admin/api/forgot-password.d.ts +39 -0
  12. package/dist/admin/api/forgot-password.d.ts.map +1 -0
  13. package/dist/admin/api/forgot-password.js +66 -0
  14. package/dist/admin/api/forgot-password.js.map +1 -0
  15. package/dist/admin/api/index.d.ts +6 -0
  16. package/dist/admin/api/index.d.ts.map +1 -1
  17. package/dist/admin/api/index.js +9 -0
  18. package/dist/admin/api/index.js.map +1 -1
  19. package/dist/admin/api/me.d.ts +72 -0
  20. package/dist/admin/api/me.d.ts.map +1 -0
  21. package/dist/admin/api/me.js +177 -0
  22. package/dist/admin/api/me.js.map +1 -0
  23. package/dist/admin/api/orders.d.ts.map +1 -1
  24. package/dist/admin/api/orders.js +21 -28
  25. package/dist/admin/api/orders.js.map +1 -1
  26. package/dist/admin/api/products.d.ts.map +1 -1
  27. package/dist/admin/api/products.js +33 -37
  28. package/dist/admin/api/products.js.map +1 -1
  29. package/dist/admin/api/refund.d.ts.map +1 -1
  30. package/dist/admin/api/refund.js +5 -7
  31. package/dist/admin/api/refund.js.map +1 -1
  32. package/dist/admin/api/reset-password.d.ts +49 -0
  33. package/dist/admin/api/reset-password.d.ts.map +1 -0
  34. package/dist/admin/api/reset-password.js +99 -0
  35. package/dist/admin/api/reset-password.js.map +1 -0
  36. package/dist/admin/api/return.d.ts.map +1 -1
  37. package/dist/admin/api/return.js +9 -12
  38. package/dist/admin/api/return.js.map +1 -1
  39. package/dist/admin/api/settings.d.ts.map +1 -1
  40. package/dist/admin/api/settings.js +9 -12
  41. package/dist/admin/api/settings.js.map +1 -1
  42. package/dist/admin/api/shipping.d.ts.map +1 -1
  43. package/dist/admin/api/shipping.js +65 -61
  44. package/dist/admin/api/shipping.js.map +1 -1
  45. package/dist/admin/api/stats.d.ts.map +1 -1
  46. package/dist/admin/api/stats.js +5 -7
  47. package/dist/admin/api/stats.js.map +1 -1
  48. package/dist/admin/api/stripe-status.d.ts.map +1 -1
  49. package/dist/admin/api/stripe-status.js +5 -7
  50. package/dist/admin/api/stripe-status.js.map +1 -1
  51. package/dist/admin/api/tax-zones.d.ts.map +1 -1
  52. package/dist/admin/api/tax-zones.js +21 -28
  53. package/dist/admin/api/tax-zones.js.map +1 -1
  54. package/dist/admin/api/users.d.ts +142 -0
  55. package/dist/admin/api/users.d.ts.map +1 -0
  56. package/dist/admin/api/users.js +356 -0
  57. package/dist/admin/api/users.js.map +1 -0
  58. package/dist/admin/components/AdminAcceptInviteForm.d.ts +3 -0
  59. package/dist/admin/components/AdminAcceptInviteForm.d.ts.map +1 -0
  60. package/dist/admin/components/AdminAcceptInviteForm.js +137 -0
  61. package/dist/admin/components/AdminAcceptInviteForm.js.map +1 -0
  62. package/dist/admin/components/AdminAccountPage.d.ts +10 -0
  63. package/dist/admin/components/AdminAccountPage.d.ts.map +1 -0
  64. package/dist/admin/components/AdminAccountPage.js +123 -0
  65. package/dist/admin/components/AdminAccountPage.js.map +1 -0
  66. package/dist/admin/components/AdminForgotPasswordForm.d.ts +8 -0
  67. package/dist/admin/components/AdminForgotPasswordForm.d.ts.map +1 -0
  68. package/dist/admin/components/AdminForgotPasswordForm.js +59 -0
  69. package/dist/admin/components/AdminForgotPasswordForm.js.map +1 -0
  70. package/dist/admin/components/AdminNav.d.ts.map +1 -1
  71. package/dist/admin/components/AdminNav.js +39 -8
  72. package/dist/admin/components/AdminNav.js.map +1 -1
  73. package/dist/admin/components/AdminResetPasswordForm.d.ts +12 -0
  74. package/dist/admin/components/AdminResetPasswordForm.d.ts.map +1 -0
  75. package/dist/admin/components/AdminResetPasswordForm.js +134 -0
  76. package/dist/admin/components/AdminResetPasswordForm.js.map +1 -0
  77. package/dist/admin/components/AdminUserMenu.d.ts.map +1 -1
  78. package/dist/admin/components/AdminUserMenu.js +2 -2
  79. package/dist/admin/components/AdminUserMenu.js.map +1 -1
  80. package/dist/admin/components/InviteUserDialog.d.ts +3 -0
  81. package/dist/admin/components/InviteUserDialog.d.ts.map +1 -0
  82. package/dist/admin/components/InviteUserDialog.js +127 -0
  83. package/dist/admin/components/InviteUserDialog.js.map +1 -0
  84. package/dist/admin/components/UsersTable.d.ts +3 -0
  85. package/dist/admin/components/UsersTable.d.ts.map +1 -0
  86. package/dist/admin/components/UsersTable.js +399 -0
  87. package/dist/admin/components/UsersTable.js.map +1 -0
  88. package/dist/admin/components/index.d.ts +9 -0
  89. package/dist/admin/components/index.d.ts.map +1 -1
  90. package/dist/admin/components/index.js +9 -0
  91. package/dist/admin/components/index.js.map +1 -1
  92. package/dist/admin/config.d.ts.map +1 -1
  93. package/dist/admin/config.js +23 -1
  94. package/dist/admin/config.js.map +1 -1
  95. package/dist/admin/hooks/index.d.ts +4 -0
  96. package/dist/admin/hooks/index.d.ts.map +1 -1
  97. package/dist/admin/hooks/index.js +3 -0
  98. package/dist/admin/hooks/index.js.map +1 -1
  99. package/dist/admin/hooks/useAdminMe.d.ts +31 -0
  100. package/dist/admin/hooks/useAdminMe.d.ts.map +1 -0
  101. package/dist/admin/hooks/useAdminMe.js +103 -0
  102. package/dist/admin/hooks/useAdminMe.js.map +1 -0
  103. package/dist/admin/hooks/useAdminPermissions.d.ts +3 -0
  104. package/dist/admin/hooks/useAdminPermissions.d.ts.map +1 -0
  105. package/dist/admin/hooks/useAdminPermissions.js +51 -0
  106. package/dist/admin/hooks/useAdminPermissions.js.map +1 -0
  107. package/dist/admin/hooks/useAdminUsers.d.ts +3 -0
  108. package/dist/admin/hooks/useAdminUsers.d.ts.map +1 -0
  109. package/dist/admin/hooks/useAdminUsers.js +240 -0
  110. package/dist/admin/hooks/useAdminUsers.js.map +1 -0
  111. package/dist/admin/index.d.ts +4 -4
  112. package/dist/admin/index.d.ts.map +1 -1
  113. package/dist/admin/index.js +20 -2
  114. package/dist/admin/index.js.map +1 -1
  115. package/dist/admin/permissions.d.ts +92 -0
  116. package/dist/admin/permissions.d.ts.map +1 -0
  117. package/dist/admin/permissions.js +201 -0
  118. package/dist/admin/permissions.js.map +1 -0
  119. package/dist/admin/server/admin-invite.d.ts +122 -0
  120. package/dist/admin/server/admin-invite.d.ts.map +1 -0
  121. package/dist/admin/server/admin-invite.js +235 -0
  122. package/dist/admin/server/admin-invite.js.map +1 -0
  123. package/dist/admin/server/admin-password-reset.d.ts +87 -0
  124. package/dist/admin/server/admin-password-reset.d.ts.map +1 -0
  125. package/dist/admin/server/admin-password-reset.js +220 -0
  126. package/dist/admin/server/admin-password-reset.js.map +1 -0
  127. package/dist/admin/server/admin-self-service.d.ts +86 -0
  128. package/dist/admin/server/admin-self-service.d.ts.map +1 -0
  129. package/dist/admin/server/admin-self-service.js +188 -0
  130. package/dist/admin/server/admin-self-service.js.map +1 -0
  131. package/dist/admin/server/admin-service.d.ts.map +1 -1
  132. package/dist/admin/server/admin-service.js +21 -2
  133. package/dist/admin/server/admin-service.js.map +1 -1
  134. package/dist/admin/server/admin-session.d.ts +126 -0
  135. package/dist/admin/server/admin-session.d.ts.map +1 -0
  136. package/dist/admin/server/admin-session.js +215 -0
  137. package/dist/admin/server/admin-session.js.map +1 -0
  138. package/dist/admin/server/index.d.ts +7 -0
  139. package/dist/admin/server/index.d.ts.map +1 -1
  140. package/dist/admin/server/index.js +20 -0
  141. package/dist/admin/server/index.js.map +1 -1
  142. package/dist/admin/server/user-management.d.ts +223 -0
  143. package/dist/admin/server/user-management.d.ts.map +1 -0
  144. package/dist/admin/server/user-management.js +846 -0
  145. package/dist/admin/server/user-management.js.map +1 -0
  146. package/dist/admin/types.d.ts +153 -2
  147. package/dist/admin/types.d.ts.map +1 -1
  148. package/dist/core/db/queries.d.ts +19 -13
  149. package/dist/core/db/queries.d.ts.map +1 -1
  150. package/dist/core/db/schema.d.ts +327 -9
  151. package/dist/core/db/schema.d.ts.map +1 -1
  152. package/dist/core/db/schema.js +80 -3
  153. package/dist/core/db/schema.js.map +1 -1
  154. package/dist/core/types.d.ts +19 -3
  155. package/dist/core/types.d.ts.map +1 -1
  156. package/dist/emails/index.d.ts +2 -2
  157. package/dist/emails/index.d.ts.map +1 -1
  158. package/dist/emails/index.js +3 -1
  159. package/dist/emails/index.js.map +1 -1
  160. package/dist/emails/send/admin-auth.d.ts +94 -0
  161. package/dist/emails/send/admin-auth.d.ts.map +1 -0
  162. package/dist/emails/send/admin-auth.js +118 -0
  163. package/dist/emails/send/admin-auth.js.map +1 -0
  164. package/dist/emails/send/index.d.ts +2 -0
  165. package/dist/emails/send/index.d.ts.map +1 -1
  166. package/dist/emails/send/index.js +4 -0
  167. package/dist/emails/send/index.js.map +1 -1
  168. package/dist/emails/templates/admin-invite.d.ts +40 -0
  169. package/dist/emails/templates/admin-invite.d.ts.map +1 -0
  170. package/dist/emails/templates/admin-invite.js +62 -0
  171. package/dist/emails/templates/admin-invite.js.map +1 -0
  172. package/dist/emails/templates/index.d.ts +1 -0
  173. package/dist/emails/templates/index.d.ts.map +1 -1
  174. package/dist/emails/templates/index.js +4 -0
  175. package/dist/emails/templates/index.js.map +1 -1
  176. package/dist/emails/types.d.ts +22 -1
  177. package/dist/emails/types.d.ts.map +1 -1
  178. package/package.json +21 -1
@@ -1 +1 @@
1
- {"version":3,"file":"admin-service.js","sourceRoot":"","sources":["../../../src/admin/server/admin-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-service.js","sourceRoot":"","sources":["../../../src/admin/server/admin-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @rovela/sdk/admin/server/admin-session
3
+ *
4
+ * Centralized session + permission check for admin API routes.
5
+ *
6
+ * # Why this exists
7
+ *
8
+ * Before this module, every admin API handler had its own local copy of a
9
+ * `requireAdmin()` helper — ten copies across products, orders, customers,
10
+ * refund, return, settings, stats, stripe-status, categories, shipping, and
11
+ * tax-zones. They were subtly buggy (imported the CUSTOMER `createAuthOptions`
12
+ * instead of the admin one, accidentally working because NextAuth cookies
13
+ * overlap), and they had no way to express role-based permissions.
14
+ *
15
+ * This module replaces all ten with a single helper that:
16
+ * 1. Reads the NextAuth session from the correct admin config.
17
+ * 2. Fetches a fresh admin row from the DB and confirms `status = 'active'`
18
+ * so that deactivated users are kicked out on their next request without
19
+ * waiting for the JWT to expire.
20
+ * 3. Optionally checks a specific `Permission` from the permission matrix.
21
+ * 4. Optionally enforces a minimum role rank via `meetsMinRole`.
22
+ * 5. Ensures the runtime schema migration has run (once per process) so
23
+ * stores on an older schema still work with the new SDK code paths.
24
+ *
25
+ * # Caching
26
+ *
27
+ * The DB status check is cached in-memory for 30 seconds per admin ID. This
28
+ * keeps the hot path fast (most admin routes already do a DB query for their
29
+ * actual work; one extra read would add ~10ms, and we want to avoid even
30
+ * that for back-to-back requests). Cache is invalidated via
31
+ * `invalidateAdminSession(adminId)` after any user-management operation that
32
+ * changes the admin's role or status, so the next request sees the new state
33
+ * without waiting for the 30-second TTL.
34
+ *
35
+ * # Schema assumptions
36
+ *
37
+ * This helper assumes the store's Neon database is already on the latest
38
+ * admin schema (v2). Schema is applied manually via Neon MCP once per store
39
+ * (master branch for new stores, per-branch for existing stores that want
40
+ * the feature). The helper tolerates missing fields gracefully: if the
41
+ * `status` column doesn't exist on an older store, it's read as undefined
42
+ * and defaulted to 'active' so existing owner sessions keep working.
43
+ *
44
+ * # Return contract
45
+ *
46
+ * `requireAdmin()` returns a discriminated union:
47
+ * - `{ ok: true, admin }` — caller proceeds
48
+ * - `{ ok: false, response }` — caller returns `response` directly
49
+ *
50
+ * This pattern keeps the happy path terse at call sites:
51
+ *
52
+ * ```ts
53
+ * const guard = await requireAdmin({ permission: 'products.write' })
54
+ * if (!guard.ok) return guard.response
55
+ * const { admin } = guard
56
+ * // ...proceed with admin.id, admin.role, etc.
57
+ * ```
58
+ */
59
+ import { NextResponse } from 'next/server';
60
+ import { type Permission } from '../permissions';
61
+ import type { AdminRole } from '../../core/types';
62
+ import type { StoreAdmin } from '../../core/db/schema';
63
+ import type { AdminApiError } from '../types';
64
+ export interface RequireAdminOptions {
65
+ /** Require a specific permission from the permission matrix. */
66
+ permission?: Permission;
67
+ /** Require at least this role rank (e.g. 'administrator' means owner OR administrator). */
68
+ minRole?: AdminRole;
69
+ }
70
+ export type RequireAdminResult = {
71
+ ok: true;
72
+ admin: StoreAdmin;
73
+ } | {
74
+ ok: false;
75
+ response: NextResponse<AdminApiError>;
76
+ };
77
+ /**
78
+ * Invalidate the session cache for a specific admin. Call this after any
79
+ * user-management operation that changes the admin's role or status, so the
80
+ * next request sees the new state without waiting for the 30s TTL.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * await deactivateAdmin(adminId)
85
+ * invalidateAdminSession(adminId)
86
+ * ```
87
+ */
88
+ export declare function invalidateAdminSession(adminId: string): void;
89
+ /**
90
+ * Clear the entire admin session cache. Exposed for tests; rarely needed in
91
+ * production since per-admin invalidation is sufficient.
92
+ * @internal
93
+ */
94
+ export declare function __clearAdminSessionCache(): void;
95
+ /**
96
+ * Authenticate + authorize the current request as an admin.
97
+ *
98
+ * Resolves with either `{ ok: true, admin }` (caller may proceed) or
99
+ * `{ ok: false, response }` (caller returns `response` to the client).
100
+ *
101
+ * Never throws — any internal error is converted to a 401/403/500 response
102
+ * that's safe to return directly.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * // List products (any authenticated admin with 'products.read')
107
+ * export async function GET(request: NextRequest) {
108
+ * const guard = await requireAdmin({ permission: 'products.read' })
109
+ * if (!guard.ok) return guard.response
110
+ * const { admin } = guard
111
+ * // ...proceed, admin.role is known, admin.status === 'active'
112
+ * }
113
+ * ```
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * // Change a user's role (only owners)
118
+ * export async function PATCH(request: NextRequest) {
119
+ * const guard = await requireAdmin({ permission: 'users.write' })
120
+ * if (!guard.ok) return guard.response
121
+ * // ...
122
+ * }
123
+ * ```
124
+ */
125
+ export declare function requireAdmin(options?: RequireAdminOptions): Promise<RequireAdminResult>;
126
+ //# sourceMappingURL=admin-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-session.d.ts","sourceRoot":"","sources":["../../../src/admin/server/admin-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI1C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAM7C,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;CAAE,CAAA;AA+BxD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,YAAY,CAChC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4E7B"}
@@ -0,0 +1,215 @@
1
+ /**
2
+ * @rovela/sdk/admin/server/admin-session
3
+ *
4
+ * Centralized session + permission check for admin API routes.
5
+ *
6
+ * # Why this exists
7
+ *
8
+ * Before this module, every admin API handler had its own local copy of a
9
+ * `requireAdmin()` helper — ten copies across products, orders, customers,
10
+ * refund, return, settings, stats, stripe-status, categories, shipping, and
11
+ * tax-zones. They were subtly buggy (imported the CUSTOMER `createAuthOptions`
12
+ * instead of the admin one, accidentally working because NextAuth cookies
13
+ * overlap), and they had no way to express role-based permissions.
14
+ *
15
+ * This module replaces all ten with a single helper that:
16
+ * 1. Reads the NextAuth session from the correct admin config.
17
+ * 2. Fetches a fresh admin row from the DB and confirms `status = 'active'`
18
+ * so that deactivated users are kicked out on their next request without
19
+ * waiting for the JWT to expire.
20
+ * 3. Optionally checks a specific `Permission` from the permission matrix.
21
+ * 4. Optionally enforces a minimum role rank via `meetsMinRole`.
22
+ * 5. Ensures the runtime schema migration has run (once per process) so
23
+ * stores on an older schema still work with the new SDK code paths.
24
+ *
25
+ * # Caching
26
+ *
27
+ * The DB status check is cached in-memory for 30 seconds per admin ID. This
28
+ * keeps the hot path fast (most admin routes already do a DB query for their
29
+ * actual work; one extra read would add ~10ms, and we want to avoid even
30
+ * that for back-to-back requests). Cache is invalidated via
31
+ * `invalidateAdminSession(adminId)` after any user-management operation that
32
+ * changes the admin's role or status, so the next request sees the new state
33
+ * without waiting for the 30-second TTL.
34
+ *
35
+ * # Schema assumptions
36
+ *
37
+ * This helper assumes the store's Neon database is already on the latest
38
+ * admin schema (v2). Schema is applied manually via Neon MCP once per store
39
+ * (master branch for new stores, per-branch for existing stores that want
40
+ * the feature). The helper tolerates missing fields gracefully: if the
41
+ * `status` column doesn't exist on an older store, it's read as undefined
42
+ * and defaulted to 'active' so existing owner sessions keep working.
43
+ *
44
+ * # Return contract
45
+ *
46
+ * `requireAdmin()` returns a discriminated union:
47
+ * - `{ ok: true, admin }` — caller proceeds
48
+ * - `{ ok: false, response }` — caller returns `response` directly
49
+ *
50
+ * This pattern keeps the happy path terse at call sites:
51
+ *
52
+ * ```ts
53
+ * const guard = await requireAdmin({ permission: 'products.write' })
54
+ * if (!guard.ok) return guard.response
55
+ * const { admin } = guard
56
+ * // ...proceed with admin.id, admin.role, etc.
57
+ * ```
58
+ */
59
+ import { NextResponse } from 'next/server';
60
+ import { getServerSession } from 'next-auth';
61
+ import { createAdminAuthOptions } from '../config';
62
+ import { findAdminById } from './admin-service';
63
+ import { hasPermission, meetsMinRole, } from '../permissions';
64
+ const STATUS_CACHE_TTL_MS = 30 * 1000;
65
+ const statusCache = new Map();
66
+ function getCachedAdmin(adminId) {
67
+ const entry = statusCache.get(adminId);
68
+ if (!entry)
69
+ return null;
70
+ if (Date.now() > entry.expiresAt) {
71
+ statusCache.delete(adminId);
72
+ return null;
73
+ }
74
+ return entry.admin;
75
+ }
76
+ function setCachedAdmin(adminId, admin) {
77
+ statusCache.set(adminId, {
78
+ admin,
79
+ expiresAt: Date.now() + STATUS_CACHE_TTL_MS,
80
+ });
81
+ }
82
+ /**
83
+ * Invalidate the session cache for a specific admin. Call this after any
84
+ * user-management operation that changes the admin's role or status, so the
85
+ * next request sees the new state without waiting for the 30s TTL.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * await deactivateAdmin(adminId)
90
+ * invalidateAdminSession(adminId)
91
+ * ```
92
+ */
93
+ export function invalidateAdminSession(adminId) {
94
+ statusCache.delete(adminId);
95
+ }
96
+ /**
97
+ * Clear the entire admin session cache. Exposed for tests; rarely needed in
98
+ * production since per-admin invalidation is sufficient.
99
+ * @internal
100
+ */
101
+ export function __clearAdminSessionCache() {
102
+ statusCache.clear();
103
+ }
104
+ // =============================================================================
105
+ // Response helpers
106
+ // =============================================================================
107
+ function unauthorized() {
108
+ return NextResponse.json({ error: 'Unauthorized', code: 'UNAUTHORIZED' }, { status: 401 });
109
+ }
110
+ function forbidden() {
111
+ return NextResponse.json({ error: 'Forbidden', code: 'FORBIDDEN' }, { status: 403 });
112
+ }
113
+ // =============================================================================
114
+ // Main helper
115
+ // =============================================================================
116
+ /**
117
+ * Authenticate + authorize the current request as an admin.
118
+ *
119
+ * Resolves with either `{ ok: true, admin }` (caller may proceed) or
120
+ * `{ ok: false, response }` (caller returns `response` to the client).
121
+ *
122
+ * Never throws — any internal error is converted to a 401/403/500 response
123
+ * that's safe to return directly.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * // List products (any authenticated admin with 'products.read')
128
+ * export async function GET(request: NextRequest) {
129
+ * const guard = await requireAdmin({ permission: 'products.read' })
130
+ * if (!guard.ok) return guard.response
131
+ * const { admin } = guard
132
+ * // ...proceed, admin.role is known, admin.status === 'active'
133
+ * }
134
+ * ```
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * // Change a user's role (only owners)
139
+ * export async function PATCH(request: NextRequest) {
140
+ * const guard = await requireAdmin({ permission: 'users.write' })
141
+ * if (!guard.ok) return guard.response
142
+ * // ...
143
+ * }
144
+ * ```
145
+ */
146
+ export async function requireAdmin(options = {}) {
147
+ // 1. NextAuth session — MUST use the admin auth options. The old duplicated
148
+ // helpers accidentally imported the CUSTOMER auth config and it worked
149
+ // because NextAuth cookies happened to overlap. Fixed here.
150
+ // The `as unknown as` dance is unavoidable: getServerSession's overloaded
151
+ // return type infers to `{}` in this generic context, and our session user
152
+ // carries a custom `role` field we need to read.
153
+ let rawSession;
154
+ try {
155
+ rawSession = await getServerSession(createAdminAuthOptions());
156
+ }
157
+ catch (err) {
158
+ console.error('[requireAdmin] Failed to read session:', err);
159
+ return { ok: false, response: unauthorized() };
160
+ }
161
+ const sessionUser = rawSession?.user;
162
+ if (!sessionUser?.id) {
163
+ return { ok: false, response: unauthorized() };
164
+ }
165
+ // 2. Fresh DB status check (cached 30s per admin).
166
+ let admin = getCachedAdmin(sessionUser.id);
167
+ if (!admin) {
168
+ try {
169
+ const fetched = await findAdminById(sessionUser.id);
170
+ if (!fetched) {
171
+ return { ok: false, response: unauthorized() };
172
+ }
173
+ admin = fetched;
174
+ setCachedAdmin(sessionUser.id, admin);
175
+ }
176
+ catch (err) {
177
+ console.error('[requireAdmin] Failed to fetch admin row:', err);
178
+ return { ok: false, response: unauthorized() };
179
+ }
180
+ }
181
+ // 3. Status must be 'active'. 'invited' admins cannot use the dashboard
182
+ // until they accept their invite; 'deactivated' admins are blocked entirely.
183
+ // The `status` column may not exist on stores running an older schema — in
184
+ // that case the field is undefined and we treat it as 'active' (backward
185
+ // compatible for stores that haven't run the v2 migration yet).
186
+ const status = admin.status ?? 'active';
187
+ if (status !== 'active') {
188
+ return { ok: false, response: unauthorized() };
189
+ }
190
+ // 4. Session version check (Phase 4). Compare the JWT's embedded
191
+ // `sessionVersion` to the DB row's current version. On any mismatch,
192
+ // treat as forced logout.
193
+ //
194
+ // Backward compatibility: JWTs issued before Phase 4 have no
195
+ // sessionVersion claim (→ undefined → 0), and all DB rows start at 0
196
+ // after the migration, so pre-Phase-4 sessions match cleanly. The
197
+ // first password change for any admin bumps the DB version to 1;
198
+ // their old JWTs fail the match on the next request and get kicked
199
+ // out — which is exactly what we want.
200
+ const jwtVersion = sessionUser.sessionVersion ?? 0;
201
+ const dbVersion = admin.sessionVersion ?? 0;
202
+ if (jwtVersion !== dbVersion) {
203
+ return { ok: false, response: unauthorized() };
204
+ }
205
+ // 5. Permission check (if requested).
206
+ if (options.permission && !hasPermission(admin.role, options.permission)) {
207
+ return { ok: false, response: forbidden() };
208
+ }
209
+ // 6. Min-role check (if requested).
210
+ if (options.minRole && !meetsMinRole(admin.role, options.minRole)) {
211
+ return { ok: false, response: forbidden() };
212
+ }
213
+ return { ok: true, admin };
214
+ }
215
+ //# sourceMappingURL=admin-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-session.js","sourceRoot":"","sources":["../../../src/admin/server/admin-session.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,11 @@
5
5
  * Re-exports from admin-service for cleaner imports.
6
6
  */
7
7
  export { authenticateAdmin, createAdmin, findAdminForSession, findAdminByEmail, findAdminById, updateAdmin, updateAdminPassword, adminEmailExists, countAdmins, type CreateAdminResult, type AuthenticateAdminResult, type AuthenticateAdminError, } from './admin-service';
8
+ export { requestAdminPasswordReset, validateAdminResetToken, resetAdminPassword, deleteAdminPasswordResetTokens, cleanupExpiredAdminResetTokens, } from './admin-password-reset';
9
+ export { listAdmins, countActiveOwners, deactivateAdmin, reactivateAdmin, hardDeleteAdmin, statusCodeFor, inviteAdmin, resendAdminInvite, cancelAdminInvite, changeAdminRole, } from './user-management';
10
+ export type { Actor, AdminListOptions, UserManagementError, UserManagementResult, InviteAdminRequest, InviteAdminSuccess, InviteAdminResult, ResendInviteSuccess, ResendInviteResult, } from './user-management';
11
+ export { validateInviteToken, acceptAdminInvite, deleteAdminInviteTokens, cleanupExpiredInviteTokens, createInviteToken, INVITE_EXPIRY_HOURS, } from './admin-invite';
12
+ export type { AdminInviteSnapshot, ValidateInviteResult, AcceptInviteResult, } from './admin-invite';
13
+ export { changeOwnPassword, updateOwnProfile, } from './admin-self-service';
14
+ export type { SelfServiceError, ChangeOwnPasswordResult, UpdateOwnProfileResult, } from './admin-self-service';
8
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/admin/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEL,iBAAiB,EAEjB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EAEX,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/admin/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEL,iBAAiB,EAEjB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EAEX,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,iBAAiB,CAAA;AAMxB,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,wBAAwB,CAAA;AAM/B,OAAO,EAEL,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EAEb,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EACV,KAAK,EACL,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAM1B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,0BAA0B,EAC1B,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AAMvB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA"}
@@ -12,4 +12,24 @@ export {
12
12
  authenticateAdmin,
13
13
  // CRUD
14
14
  createAdmin, findAdminForSession, findAdminByEmail, findAdminById, updateAdmin, updateAdminPassword, adminEmailExists, countAdmins, } from './admin-service';
15
+ // =============================================================================
16
+ // Admin Password Reset Service
17
+ // =============================================================================
18
+ export { requestAdminPasswordReset, validateAdminResetToken, resetAdminPassword, deleteAdminPasswordResetTokens, cleanupExpiredAdminResetTokens, } from './admin-password-reset';
19
+ // =============================================================================
20
+ // User Management (Phase 2 + Phase 3)
21
+ // =============================================================================
22
+ export {
23
+ // Phase 2
24
+ listAdmins, countActiveOwners, deactivateAdmin, reactivateAdmin, hardDeleteAdmin, statusCodeFor,
25
+ // Phase 3
26
+ inviteAdmin, resendAdminInvite, cancelAdminInvite, changeAdminRole, } from './user-management';
27
+ // =============================================================================
28
+ // Admin Invite Token Service (Phase 3)
29
+ // =============================================================================
30
+ export { validateInviteToken, acceptAdminInvite, deleteAdminInviteTokens, cleanupExpiredInviteTokens, createInviteToken, INVITE_EXPIRY_HOURS, } from './admin-invite';
31
+ // =============================================================================
32
+ // Self-Service (Phase 4)
33
+ // =============================================================================
34
+ export { changeOwnPassword, updateOwnProfile, } from './admin-self-service';
15
35
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/admin/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO;AACL,iBAAiB;AACjB,iBAAiB;AACjB,OAAO;AACP,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GAKZ,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/admin/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO;AACL,iBAAiB;AACjB,iBAAiB;AACjB,OAAO;AACP,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GAKZ,MAAM,iBAAiB,CAAA;AAExB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,wBAAwB,CAAA;AAE/B,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAEhF,OAAO;AACL,UAAU;AACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa;AACb,UAAU;AACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAe1B,gFAAgF;AAChF,uCAAuC;AACvC,gFAAgF;AAEhF,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,0BAA0B,EAC1B,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAQvB,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @rovela/sdk/admin/server/user-management
3
+ *
4
+ * User lifecycle management for store admins — list, deactivate, reactivate,
5
+ * and hard-delete operations, with all invariants enforced at the service
6
+ * layer so every future caller inherits them automatically.
7
+ *
8
+ * # Invariants (enforced in every mutation)
9
+ *
10
+ * 1. Self-protection: actor cannot act on themselves via these helpers.
11
+ * Self-service flows (password change, profile update) go through
12
+ * dedicated `/api/admin/me/*` endpoints (Phase 4).
13
+ *
14
+ * 2. Last-owner protection: there must ALWAYS be at least one admin with
15
+ * role='owner' AND status='active'. Deactivating, demoting, or deleting
16
+ * the last active owner is rejected. This is enforced via an atomic
17
+ * conditional UPDATE (or a pre-check for hard delete), not a
18
+ * check-then-act pattern — no TOCTOU race window.
19
+ *
20
+ * 3. Lateral-escalation protection: administrators can only touch managers
21
+ * and users. They cannot modify owners or other administrators.
22
+ * Enforced via `canManageUser(actor, target)` from `permissions.ts`.
23
+ *
24
+ * 4. Hard delete requires prior deactivation: you cannot DELETE an admin
25
+ * whose status is 'active' or 'invited'. Must call `deactivateAdmin`
26
+ * first. This creates a two-step safety rail for irreversible actions.
27
+ *
28
+ * 5. Audit trail on deactivate: `deactivated_at` and `deactivated_by` are
29
+ * populated from the service layer. Reactivate clears them.
30
+ *
31
+ * 6. Reactivate only applies to 'deactivated' admins, not 'invited'.
32
+ * Invited admins must accept their invite (Phase 3) to become active.
33
+ *
34
+ * # Session cache invalidation
35
+ *
36
+ * Every mutation ends with `invalidateAdminSession(targetId)` so the 30-second
37
+ * per-admin status cache in `requireAdmin()` sees the new state on the very
38
+ * next request. Without this call, a deactivated admin could continue making
39
+ * authenticated requests for up to 30 seconds.
40
+ *
41
+ * # This module never throws on invariant failures — it returns a typed
42
+ * discriminated union `{ ok: true }` or `{ ok: false, error: {...} }`.
43
+ * Unexpected runtime errors (DB connectivity, etc.) still throw and bubble
44
+ * up to the API route's try/catch.
45
+ */
46
+ import type { AdminRole } from '../../core/types';
47
+ import type { StoreAdmin } from '../../core/db/schema';
48
+ export interface AdminListOptions {
49
+ /** Case-insensitive substring match against name OR email. */
50
+ search?: string;
51
+ /** Filter by status. 'all' (default) returns every admin regardless of status. */
52
+ status?: 'all' | 'active' | 'invited' | 'deactivated';
53
+ /** Filter by role. 'all' (default) returns every admin regardless of role. */
54
+ role?: 'all' | AdminRole;
55
+ /** Max rows to return. Clamped to 1..100 at the API layer. */
56
+ limit?: number;
57
+ /** Offset for pagination (0-indexed). */
58
+ offset?: number;
59
+ }
60
+ export interface UserManagementError {
61
+ code: 'NOT_FOUND' | 'FORBIDDEN' | 'SELF_ACTION_FORBIDDEN' | 'LAST_OWNER_PROTECTED' | 'MUST_DEACTIVATE_FIRST' | 'INVALID_STATE' | 'VALIDATION_ERROR' | 'EMAIL_ALREADY_EXISTS' | 'EMAIL_ALREADY_INVITED' | 'EMAIL_DEACTIVATED_EXISTS';
62
+ message: string;
63
+ }
64
+ export type UserManagementResult = {
65
+ ok: true;
66
+ } | {
67
+ ok: false;
68
+ error: UserManagementError;
69
+ };
70
+ export interface Actor {
71
+ id: string;
72
+ role: AdminRole;
73
+ }
74
+ /**
75
+ * List admins with filters and pagination.
76
+ *
77
+ * Returns the raw `StoreAdmin` rows — the caller is responsible for stripping
78
+ * sensitive fields (`passwordHash`) before serializing to JSON. The API
79
+ * handler does this mapping.
80
+ */
81
+ export declare function listAdmins(opts?: AdminListOptions): Promise<{
82
+ admins: StoreAdmin[];
83
+ total: number;
84
+ }>;
85
+ /**
86
+ * Count admins with role='owner' and status='active'.
87
+ *
88
+ * The single source of truth for the last-owner invariant. Always queried
89
+ * fresh — it's a one-row COUNT, trivially fast, and caching would introduce
90
+ * staleness risk for a safety-critical check.
91
+ */
92
+ export declare function countActiveOwners(): Promise<number>;
93
+ /**
94
+ * Soft-delete an admin: set status='deactivated' and stamp audit fields.
95
+ *
96
+ * Rejects on any invariant violation. Never throws on business errors;
97
+ * returns a typed result the caller can branch on.
98
+ *
99
+ * Uses an atomic conditional UPDATE to enforce the last-owner invariant —
100
+ * no check-then-act race window. If another request deactivates the second-
101
+ * to-last owner between our check and our update, our UPDATE's WHERE clause
102
+ * will match zero rows and we return LAST_OWNER_PROTECTED.
103
+ */
104
+ export declare function deactivateAdmin(actor: Actor, targetId: string): Promise<UserManagementResult>;
105
+ /**
106
+ * Reactivate a previously-deactivated admin: set status='active', clear
107
+ * audit fields. Does NOT apply to 'invited' admins — they must accept
108
+ * their invite (Phase 3) to become active.
109
+ */
110
+ export declare function reactivateAdmin(actor: Actor, targetId: string): Promise<UserManagementResult>;
111
+ /**
112
+ * Permanently delete an admin row. Cascades to `admin_password_reset_tokens`
113
+ * and `admin_invite_tokens` via the `ON DELETE CASCADE` foreign keys defined
114
+ * in the Phase 0 schema.
115
+ *
116
+ * Requires the target to already be 'deactivated' — this is a two-step
117
+ * irreversible action. The API route additionally gates on `users.delete`
118
+ * permission (owner-only), but we re-check here for defense-in-depth.
119
+ *
120
+ * Dangling `deactivated_by` / `created_by` references on other admin rows
121
+ * are intentionally left as dangling UUIDs. The UI renders them as
122
+ * "Unknown user". Phase 4 may revisit.
123
+ */
124
+ export declare function hardDeleteAdmin(actor: Actor, targetId: string): Promise<UserManagementResult>;
125
+ /**
126
+ * Map a `UserManagementError.code` to the HTTP status the API handler
127
+ * should respond with. Exported so both the API handlers and any future
128
+ * caller use the same mapping.
129
+ */
130
+ export declare function statusCodeFor(code: UserManagementError['code']): number;
131
+ export interface InviteAdminRequest {
132
+ email: string;
133
+ name: string;
134
+ role: AdminRole;
135
+ }
136
+ export interface InviteAdminSuccess {
137
+ ok: true;
138
+ adminId: string;
139
+ token: string;
140
+ inviteUrl: string;
141
+ }
142
+ export type InviteAdminResult = InviteAdminSuccess | {
143
+ ok: false;
144
+ error: UserManagementError;
145
+ };
146
+ /**
147
+ * Invite a new admin to manage the store.
148
+ *
149
+ * Creates a `store_admins` row in `invited` status with no password,
150
+ * issues an invite token (72h expiry), and sends the invite email. The
151
+ * caller receives both the token AND the fully-qualified invite URL — so
152
+ * if email delivery fails, the UI can show a "copy link manually"
153
+ * fallback instead of silently losing the invite.
154
+ *
155
+ * # Invariants (in order)
156
+ *
157
+ * 1. `canManageUser(actor, {role})` — actor can grant the requested role.
158
+ * Administrators cannot invite owners or other administrators.
159
+ * 2. Valid email format + name length ≥ 2.
160
+ * 3. Email uniqueness — rejects with a distinct error code depending on
161
+ * the existing row's status (active / invited / deactivated) so the
162
+ * UI can show actionable messages.
163
+ * 4. Legal role: must be one of 'owner' | 'administrator' | 'manager' | 'user'.
164
+ * The legacy 'admin' value is never chosen by the caller here — new
165
+ * invites always use the canonical names.
166
+ *
167
+ * Email send failures are logged but NOT propagated — the invite row +
168
+ * token are already persisted, the caller gets the URL, and the UI
169
+ * handles fallback display.
170
+ */
171
+ export declare function inviteAdmin(actor: Actor, request: InviteAdminRequest): Promise<InviteAdminResult>;
172
+ export interface ResendInviteSuccess {
173
+ ok: true;
174
+ token: string;
175
+ inviteUrl: string;
176
+ }
177
+ export type ResendInviteResult = ResendInviteSuccess | {
178
+ ok: false;
179
+ error: UserManagementError;
180
+ };
181
+ /**
182
+ * Resend an invite to an admin who is still in `invited` status.
183
+ *
184
+ * Generates a fresh token (invalidating any previous ones) and resends
185
+ * the email. Preserves the single-active-token policy — older tokens
186
+ * are deleted before the new one is created.
187
+ */
188
+ export declare function resendAdminInvite(actor: Actor, targetId: string): Promise<ResendInviteResult>;
189
+ /**
190
+ * Cancel a pending invite. Hard-deletes the `store_admins` row — which
191
+ * cascades via FK to delete all `admin_invite_tokens` rows for that
192
+ * admin. Only valid for `invited` status (not `active` / `deactivated`).
193
+ *
194
+ * Uses `users.write` permission (administrators + owners), unlike the
195
+ * DELETE endpoint which is owner-only. Canceling an invite for a manager
196
+ * or user is a normal administrator action, not a destructive one.
197
+ */
198
+ export declare function cancelAdminInvite(actor: Actor, targetId: string): Promise<UserManagementResult>;
199
+ /**
200
+ * Change an admin's role.
201
+ *
202
+ * Invariants (in strict order):
203
+ *
204
+ * 1. Target exists (→ NOT_FOUND).
205
+ * 2. Self-protection — actor cannot change their own role (→
206
+ * SELF_ACTION_FORBIDDEN). A solo owner needing to demote themselves
207
+ * must either invite another owner first, or use a future Phase 4
208
+ * emergency-reset flow.
209
+ * 3. canManageUser at CURRENT role — actor must be allowed to manage
210
+ * the target at their current role (administrator cannot touch
211
+ * owners or other administrators).
212
+ * 4. canManageUser at NEW role — actor must be allowed to grant the
213
+ * new role (administrator cannot promote to administrator/owner).
214
+ * 5. No-op fast path — if newRole === current role, return success
215
+ * without touching the DB.
216
+ * 6. Last-owner protection — if target is currently 'owner' and the
217
+ * new role is not 'owner', require `countActiveOwners() > 1`.
218
+ * Enforced atomically via a conditional UPDATE so there's no
219
+ * check-then-act race window.
220
+ * 7. Update; invalidate session cache.
221
+ */
222
+ export declare function changeAdminRole(actor: Actor, targetId: string, newRole: AdminRole): Promise<UserManagementResult>;
223
+ //# sourceMappingURL=user-management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-management.d.ts","sourceRoot":"","sources":["../../../src/admin/server/user-management.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAetD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAA;IACrD,8EAA8E;IAC9E,IAAI,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;IACxB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EACA,WAAW,GACX,WAAW,GACX,uBAAuB,GACvB,sBAAsB,GACtB,uBAAuB,GACvB,eAAe,GAEf,kBAAkB,GAClB,sBAAsB,GACtB,uBAAuB,GACvB,0BAA0B,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE7C,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,SAAS,CAAA;CAChB;AAMD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC;IACrE,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CA0DD;AAMD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAYzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAmH/B;AAMD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAqE/B;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAgG/B;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG,MAAM,CAqBvE;AAMD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,SAAS,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA2J5B;AAMD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,kBAAkB,GAC1B,mBAAmB,GACnB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE7C;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,CAAC,CA8D7B;AAMD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAgE/B;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,oBAAoB,CAAC,CAsH/B"}