@sudobility/shapeshyft_service 1.0.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 (127) hide show
  1. package/CLAUDE.md +35 -0
  2. package/README.md +17 -0
  3. package/dist/context.d.ts +62 -0
  4. package/dist/context.d.ts.map +1 -0
  5. package/dist/context.js +55 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/contracts.d.ts +110 -0
  8. package/dist/contracts.d.ts.map +1 -0
  9. package/dist/contracts.js +7 -0
  10. package/dist/contracts.js.map +1 -0
  11. package/dist/index.d.ts +17 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +16 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/api-key.d.ts +22 -0
  16. package/dist/lib/api-key.d.ts.map +1 -0
  17. package/dist/lib/api-key.js +87 -0
  18. package/dist/lib/api-key.js.map +1 -0
  19. package/dist/lib/encryption.d.ts +22 -0
  20. package/dist/lib/encryption.d.ts.map +1 -0
  21. package/dist/lib/encryption.js +41 -0
  22. package/dist/lib/encryption.js.map +1 -0
  23. package/dist/lib/entity-api-key.d.ts +21 -0
  24. package/dist/lib/entity-api-key.d.ts.map +1 -0
  25. package/dist/lib/entity-api-key.js +54 -0
  26. package/dist/lib/entity-api-key.js.map +1 -0
  27. package/dist/lib/entity-helpers.d.ts +90 -0
  28. package/dist/lib/entity-helpers.d.ts.map +1 -0
  29. package/dist/lib/entity-helpers.js +136 -0
  30. package/dist/lib/entity-helpers.js.map +1 -0
  31. package/dist/lib/money.d.ts +7 -0
  32. package/dist/lib/money.d.ts.map +1 -0
  33. package/dist/lib/money.js +9 -0
  34. package/dist/lib/money.js.map +1 -0
  35. package/dist/lib/public-project.d.ts +14 -0
  36. package/dist/lib/public-project.d.ts.map +1 -0
  37. package/dist/lib/public-project.js +17 -0
  38. package/dist/lib/public-project.js.map +1 -0
  39. package/dist/lib/user-api-key-cache.d.ts +35 -0
  40. package/dist/lib/user-api-key-cache.d.ts.map +1 -0
  41. package/dist/lib/user-api-key-cache.js +99 -0
  42. package/dist/lib/user-api-key-cache.js.map +1 -0
  43. package/dist/lib/user-api-key.d.ts +46 -0
  44. package/dist/lib/user-api-key.d.ts.map +1 -0
  45. package/dist/lib/user-api-key.js +102 -0
  46. package/dist/lib/user-api-key.js.map +1 -0
  47. package/dist/middleware/firebaseAuth.d.ts +34 -0
  48. package/dist/middleware/firebaseAuth.d.ts.map +1 -0
  49. package/dist/middleware/firebaseAuth.js +133 -0
  50. package/dist/middleware/firebaseAuth.js.map +1 -0
  51. package/dist/middleware/rateLimit.d.ts +29 -0
  52. package/dist/middleware/rateLimit.d.ts.map +1 -0
  53. package/dist/middleware/rateLimit.js +85 -0
  54. package/dist/middleware/rateLimit.js.map +1 -0
  55. package/dist/middleware/subscription.d.ts +8 -0
  56. package/dist/middleware/subscription.d.ts.map +1 -0
  57. package/dist/middleware/subscription.js +19 -0
  58. package/dist/middleware/subscription.js.map +1 -0
  59. package/dist/routes/ai.d.ts +10 -0
  60. package/dist/routes/ai.d.ts.map +1 -0
  61. package/dist/routes/ai.js +698 -0
  62. package/dist/routes/ai.js.map +1 -0
  63. package/dist/routes/analytics.d.ts +9 -0
  64. package/dist/routes/analytics.d.ts.map +1 -0
  65. package/dist/routes/analytics.js +192 -0
  66. package/dist/routes/analytics.js.map +1 -0
  67. package/dist/routes/endpoints.d.ts +10 -0
  68. package/dist/routes/endpoints.d.ts.map +1 -0
  69. package/dist/routes/endpoints.js +255 -0
  70. package/dist/routes/endpoints.js.map +1 -0
  71. package/dist/routes/entities.d.ts +15 -0
  72. package/dist/routes/entities.d.ts.map +1 -0
  73. package/dist/routes/entities.js +332 -0
  74. package/dist/routes/entities.js.map +1 -0
  75. package/dist/routes/entity-api-keys.d.ts +17 -0
  76. package/dist/routes/entity-api-keys.d.ts.map +1 -0
  77. package/dist/routes/entity-api-keys.js +142 -0
  78. package/dist/routes/entity-api-keys.js.map +1 -0
  79. package/dist/routes/invitations.d.ts +15 -0
  80. package/dist/routes/invitations.d.ts.map +1 -0
  81. package/dist/routes/invitations.js +58 -0
  82. package/dist/routes/invitations.js.map +1 -0
  83. package/dist/routes/projects.d.ts +9 -0
  84. package/dist/routes/projects.d.ts.map +1 -0
  85. package/dist/routes/projects.js +241 -0
  86. package/dist/routes/projects.js.map +1 -0
  87. package/dist/routes/providers.d.ts +9 -0
  88. package/dist/routes/providers.d.ts.map +1 -0
  89. package/dist/routes/providers.js +89 -0
  90. package/dist/routes/providers.js.map +1 -0
  91. package/dist/routes/ratelimits.d.ts +9 -0
  92. package/dist/routes/ratelimits.d.ts.map +1 -0
  93. package/dist/routes/ratelimits.js +171 -0
  94. package/dist/routes/ratelimits.js.map +1 -0
  95. package/dist/routes/settings.d.ts +9 -0
  96. package/dist/routes/settings.d.ts.map +1 -0
  97. package/dist/routes/settings.js +138 -0
  98. package/dist/routes/settings.js.map +1 -0
  99. package/dist/routes/storage.d.ts +9 -0
  100. package/dist/routes/storage.d.ts.map +1 -0
  101. package/dist/routes/storage.js +180 -0
  102. package/dist/routes/storage.js.map +1 -0
  103. package/dist/routes/user-api-keys.d.ts +14 -0
  104. package/dist/routes/user-api-keys.d.ts.map +1 -0
  105. package/dist/routes/user-api-keys.js +237 -0
  106. package/dist/routes/user-api-keys.js.map +1 -0
  107. package/dist/routes/users.d.ts +7 -0
  108. package/dist/routes/users.d.ts.map +1 -0
  109. package/dist/routes/users.js +102 -0
  110. package/dist/routes/users.js.map +1 -0
  111. package/dist/schema/init.d.ts +12 -0
  112. package/dist/schema/init.d.ts.map +1 -0
  113. package/dist/schema/init.js +404 -0
  114. package/dist/schema/init.js.map +1 -0
  115. package/dist/schema/tables.d.ts +2110 -0
  116. package/dist/schema/tables.d.ts.map +1 -0
  117. package/dist/schema/tables.js +251 -0
  118. package/dist/schema/tables.js.map +1 -0
  119. package/dist/schemas/index.d.ts +671 -0
  120. package/dist/schemas/index.d.ts.map +1 -0
  121. package/dist/schemas/index.js +299 -0
  122. package/dist/schemas/index.js.map +1 -0
  123. package/dist/service.d.ts +41 -0
  124. package/dist/service.d.ts.map +1 -0
  125. package/dist/service.js +70 -0
  126. package/dist/service.js.map +1 -0
  127. package/package.json +85 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * @fileoverview Entity Routes
3
+ * @description API routes for entity/organization management
4
+ */
5
+ import { Hono } from "hono";
6
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
7
+ export function createEntitiesRouter(ctx) {
8
+ const helpers = ctx.entityAccess.entityHelpers;
9
+ const sendInvitationEmail = params => ctx.email.sendInvitationEmail(params);
10
+ const entitiesRouter = new Hono();
11
+ // =============================================================================
12
+ // Entity CRUD Routes
13
+ // =============================================================================
14
+ /**
15
+ * GET /entities - List all entities for the current user
16
+ */
17
+ entitiesRouter.get("/", async (c) => {
18
+ const userId = c.get("userId"); // firebase_uid
19
+ const userEmail = c.get("userEmail");
20
+ try {
21
+ const userEntities = await helpers.entity.getUserEntities(userId, userEmail ?? undefined);
22
+ return c.json(successResponse(userEntities));
23
+ }
24
+ catch (error) {
25
+ console.error("Error listing entities:", error);
26
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
27
+ }
28
+ });
29
+ /**
30
+ * POST /entities - Create a new organization entity
31
+ */
32
+ entitiesRouter.post("/", async (c) => {
33
+ const userId = c.get("userId"); // firebase_uid
34
+ const body = await c.req.json();
35
+ const { displayName, entitySlug, description } = body;
36
+ if (!displayName) {
37
+ return c.json(errorResponse("displayName is required"), 400);
38
+ }
39
+ try {
40
+ const entity = await helpers.entity.createOrganizationEntity(userId, {
41
+ displayName,
42
+ entitySlug,
43
+ description,
44
+ });
45
+ return c.json(successResponse(entity), 201);
46
+ }
47
+ catch (error) {
48
+ console.error("Error creating entity:", error);
49
+ return c.json(errorResponse(error.message || "Bad request"), 400);
50
+ }
51
+ });
52
+ /**
53
+ * GET /entities/:entitySlug - Get entity by slug
54
+ */
55
+ entitiesRouter.get("/:entitySlug", async (c) => {
56
+ const userId = c.get("userId");
57
+ const entitySlug = c.req.param("entitySlug");
58
+ try {
59
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
60
+ if (!entity) {
61
+ return c.json(errorResponse("Entity not found"), 404);
62
+ }
63
+ // Check if user is a member
64
+ const isMember = await helpers.members.isMember(entity.id, userId);
65
+ if (!isMember) {
66
+ return c.json(errorResponse("Access denied"), 403);
67
+ }
68
+ const role = await helpers.members.getUserRole(entity.id, userId);
69
+ return c.json(successResponse({
70
+ ...entity,
71
+ userRole: role,
72
+ }));
73
+ }
74
+ catch (error) {
75
+ console.error("Error getting entity:", error);
76
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
77
+ }
78
+ });
79
+ /**
80
+ * PUT /entities/:entitySlug - Update entity
81
+ */
82
+ entitiesRouter.put("/:entitySlug", async (c) => {
83
+ const userId = c.get("userId");
84
+ const entitySlug = c.req.param("entitySlug");
85
+ const body = await c.req.json();
86
+ try {
87
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
88
+ if (!entity) {
89
+ return c.json(errorResponse("Entity not found"), 404);
90
+ }
91
+ // Check if user can edit
92
+ const canEdit = await helpers.permissions.canEditEntity(entity.id, userId);
93
+ if (!canEdit) {
94
+ return c.json(errorResponse("Insufficient permissions"), 403);
95
+ }
96
+ const updated = await helpers.entity.updateEntity(entity.id, body);
97
+ return c.json(successResponse(updated));
98
+ }
99
+ catch (error) {
100
+ console.error("Error updating entity:", error);
101
+ return c.json(errorResponse(error.message || "Bad request"), 400);
102
+ }
103
+ });
104
+ /**
105
+ * DELETE /entities/:entitySlug - Delete entity (organizations only)
106
+ */
107
+ entitiesRouter.delete("/:entitySlug", async (c) => {
108
+ const userId = c.get("userId");
109
+ const entitySlug = c.req.param("entitySlug");
110
+ try {
111
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
112
+ if (!entity) {
113
+ return c.json(errorResponse("Entity not found"), 404);
114
+ }
115
+ // Check if user can delete
116
+ const canDelete = await helpers.permissions.canDeleteEntity(entity.id, userId);
117
+ if (!canDelete) {
118
+ return c.json(errorResponse("Insufficient permissions"), 403);
119
+ }
120
+ await helpers.entity.deleteEntity(entity.id);
121
+ return c.json(successResponse(null));
122
+ }
123
+ catch (error) {
124
+ console.error("Error deleting entity:", error);
125
+ return c.json(errorResponse(error.message || "Bad request"), 400);
126
+ }
127
+ });
128
+ // =============================================================================
129
+ // Member Routes
130
+ // =============================================================================
131
+ /**
132
+ * GET /entities/:entitySlug/members - List members
133
+ */
134
+ entitiesRouter.get("/:entitySlug/members", async (c) => {
135
+ const userId = c.get("userId");
136
+ const entitySlug = c.req.param("entitySlug");
137
+ try {
138
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
139
+ if (!entity) {
140
+ return c.json(errorResponse("Entity not found"), 404);
141
+ }
142
+ // Check if user can view
143
+ const canView = await helpers.permissions.canViewEntity(entity.id, userId);
144
+ if (!canView) {
145
+ return c.json(errorResponse("Access denied"), 403);
146
+ }
147
+ const members = await helpers.members.getMembers(entity.id);
148
+ return c.json(successResponse(members));
149
+ }
150
+ catch (error) {
151
+ console.error("Error listing members:", error);
152
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
153
+ }
154
+ });
155
+ /**
156
+ * PUT /entities/:entitySlug/members/:memberId - Update member role
157
+ */
158
+ entitiesRouter.put("/:entitySlug/members/:memberId", async (c) => {
159
+ const userId = c.get("userId");
160
+ const entitySlug = c.req.param("entitySlug");
161
+ const memberId = c.req.param("memberId");
162
+ const body = await c.req.json();
163
+ const { role } = body;
164
+ if (!role) {
165
+ return c.json(errorResponse("role is required"), 400);
166
+ }
167
+ try {
168
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
169
+ if (!entity) {
170
+ return c.json(errorResponse("Entity not found"), 404);
171
+ }
172
+ // Check if user can manage members
173
+ const canManage = await helpers.permissions.canManageMembers(entity.id, userId);
174
+ if (!canManage) {
175
+ return c.json(errorResponse("Insufficient permissions"), 403);
176
+ }
177
+ const updated = await helpers.members.updateMemberRole(entity.id, memberId, role);
178
+ return c.json(successResponse(updated));
179
+ }
180
+ catch (error) {
181
+ console.error("Error updating member role:", error);
182
+ return c.json(errorResponse(error.message || "Bad request"), 400);
183
+ }
184
+ });
185
+ /**
186
+ * DELETE /entities/:entitySlug/members/:memberId - Remove member
187
+ */
188
+ entitiesRouter.delete("/:entitySlug/members/:memberId", async (c) => {
189
+ const userId = c.get("userId");
190
+ const entitySlug = c.req.param("entitySlug");
191
+ const memberId = c.req.param("memberId");
192
+ try {
193
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
194
+ if (!entity) {
195
+ return c.json(errorResponse("Entity not found"), 404);
196
+ }
197
+ // Check if user can manage members
198
+ const canManage = await helpers.permissions.canManageMembers(entity.id, userId);
199
+ if (!canManage) {
200
+ return c.json(errorResponse("Insufficient permissions"), 403);
201
+ }
202
+ await helpers.members.removeMember(entity.id, memberId);
203
+ return c.json(successResponse(null));
204
+ }
205
+ catch (error) {
206
+ console.error("Error removing member:", error);
207
+ return c.json(errorResponse(error.message || "Bad request"), 400);
208
+ }
209
+ });
210
+ // =============================================================================
211
+ // Invitation Routes
212
+ // =============================================================================
213
+ /**
214
+ * GET /entities/:entitySlug/invitations - List pending invitations
215
+ */
216
+ entitiesRouter.get("/:entitySlug/invitations", async (c) => {
217
+ const userId = c.get("userId");
218
+ const entitySlug = c.req.param("entitySlug");
219
+ try {
220
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
221
+ if (!entity) {
222
+ return c.json(errorResponse("Entity not found"), 404);
223
+ }
224
+ // Check if user can manage members (required to see invitations)
225
+ const canManage = await helpers.permissions.canManageMembers(entity.id, userId);
226
+ if (!canManage) {
227
+ return c.json(errorResponse("Insufficient permissions"), 403);
228
+ }
229
+ const invitations = await helpers.invitations.getEntityInvitations(entity.id);
230
+ return c.json(successResponse(invitations));
231
+ }
232
+ catch (error) {
233
+ console.error("Error listing invitations:", error);
234
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
235
+ }
236
+ });
237
+ /**
238
+ * POST /entities/:entitySlug/invitations - Create invitation
239
+ */
240
+ entitiesRouter.post("/:entitySlug/invitations", async (c) => {
241
+ const userId = c.get("userId");
242
+ const entitySlug = c.req.param("entitySlug");
243
+ const body = await c.req.json();
244
+ const { email, role } = body;
245
+ if (!email || !role) {
246
+ return c.json(errorResponse("email and role are required"), 400);
247
+ }
248
+ try {
249
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
250
+ if (!entity) {
251
+ return c.json(errorResponse("Entity not found"), 404);
252
+ }
253
+ // Check if user can invite members
254
+ const canInvite = await helpers.permissions.canInviteMembers(entity.id, userId);
255
+ if (!canInvite) {
256
+ return c.json(errorResponse("Insufficient permissions"), 403);
257
+ }
258
+ const invitation = await helpers.invitations.createInvitation(entity.id, userId, {
259
+ email,
260
+ role,
261
+ });
262
+ // Send invite email (non-blocking)
263
+ sendInvitationEmail({
264
+ recipientEmail: email,
265
+ entityName: entity.displayName,
266
+ }).catch(err => console.error("Failed to send invitation email:", err));
267
+ return c.json(successResponse(invitation), 201);
268
+ }
269
+ catch (error) {
270
+ console.error("Error creating invitation:", error);
271
+ return c.json(errorResponse(error.message || "Bad request"), 400);
272
+ }
273
+ });
274
+ /**
275
+ * PUT /entities/:entitySlug/invitations/:invitationId - Renew invitation
276
+ * Renews the invitation with a new 14-day expiration and optionally resends email
277
+ */
278
+ entitiesRouter.put("/:entitySlug/invitations/:invitationId", async (c) => {
279
+ const userId = c.get("userId");
280
+ const entitySlug = c.req.param("entitySlug");
281
+ const invitationId = c.req.param("invitationId");
282
+ try {
283
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
284
+ if (!entity) {
285
+ return c.json(errorResponse("Entity not found"), 404);
286
+ }
287
+ // Check if user can manage members (admin only)
288
+ const canManage = await helpers.permissions.canManageMembers(entity.id, userId);
289
+ if (!canManage) {
290
+ return c.json(errorResponse("Insufficient permissions"), 403);
291
+ }
292
+ const renewed = await helpers.invitations.renewInvitation(invitationId);
293
+ // Resend invite email (non-blocking)
294
+ sendInvitationEmail({
295
+ recipientEmail: renewed.email,
296
+ entityName: entity.displayName,
297
+ }).catch(err => console.error("Failed to resend invitation email:", err));
298
+ return c.json(successResponse(renewed));
299
+ }
300
+ catch (error) {
301
+ console.error("Error renewing invitation:", error);
302
+ return c.json(errorResponse(error.message || "Bad request"), 400);
303
+ }
304
+ });
305
+ /**
306
+ * DELETE /entities/:entitySlug/invitations/:invitationId - Cancel invitation
307
+ */
308
+ entitiesRouter.delete("/:entitySlug/invitations/:invitationId", async (c) => {
309
+ const userId = c.get("userId");
310
+ const entitySlug = c.req.param("entitySlug");
311
+ const invitationId = c.req.param("invitationId");
312
+ try {
313
+ const entity = await helpers.entity.getEntityBySlug(entitySlug);
314
+ if (!entity) {
315
+ return c.json(errorResponse("Entity not found"), 404);
316
+ }
317
+ // Check if user can manage members
318
+ const canManage = await helpers.permissions.canManageMembers(entity.id, userId);
319
+ if (!canManage) {
320
+ return c.json(errorResponse("Insufficient permissions"), 403);
321
+ }
322
+ await helpers.invitations.cancelInvitation(invitationId);
323
+ return c.json(successResponse(null));
324
+ }
325
+ catch (error) {
326
+ console.error("Error canceling invitation:", error);
327
+ return c.json(errorResponse(error.message || "Bad request"), 400);
328
+ }
329
+ });
330
+ return entitiesRouter;
331
+ }
332
+ //# sourceMappingURL=entities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/routes/entities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview Entity API key routes
3
+ * @description CRUD for entity-scoped API keys ("<entity prefix>_...").
4
+ *
5
+ * A key authenticates a caller as the entity itself, so CI jobs, scripts, and
6
+ * MCP clients keep working when the member who created them leaves. Storage is
7
+ * hash-only: the plaintext appears once in the create response and is
8
+ * unrecoverable afterwards -- a lost key is rotated, not revealed.
9
+ *
10
+ * Writes require `canManageApiKeys` (Owner or Manager); reads require
11
+ * membership. Requests authenticated *with* an entity API key cannot reach
12
+ * these routes at all -- see `assertNotEntityKeyAuth`.
13
+ */
14
+ import { Hono } from "hono";
15
+ import type { ServiceContext } from "../context.js";
16
+ export declare function createEntityApiKeysRouter(ctx: ServiceContext): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
17
+ //# sourceMappingURL=entity-api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-api-keys.d.ts","sourceRoot":"","sources":["../../src/routes/entity-api-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAY1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,8EA2N5D"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @fileoverview Entity API key routes
3
+ * @description CRUD for entity-scoped API keys ("<entity prefix>_...").
4
+ *
5
+ * A key authenticates a caller as the entity itself, so CI jobs, scripts, and
6
+ * MCP clients keep working when the member who created them leaves. Storage is
7
+ * hash-only: the plaintext appears once in the create response and is
8
+ * unrecoverable afterwards -- a lost key is rotated, not revealed.
9
+ *
10
+ * Writes require `canManageApiKeys` (Owner or Manager); reads require
11
+ * membership. Requests authenticated *with* an entity API key cannot reach
12
+ * these routes at all -- see `assertNotEntityKeyAuth`.
13
+ */
14
+ import { Hono } from "hono";
15
+ import { zValidator } from "@hono/zod-validator";
16
+ import { entityApiKeyCreateSchema, entityApiKeyUpdateSchema, entityApiKeyIdParamSchema, entitySlugParamSchema, } from "../schemas/index.js";
17
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
18
+ export function createEntityApiKeysRouter(ctx) {
19
+ const { entityHelpers, getActor, getEntityWithPermission, getPermissionErrorStatus, } = ctx.entityAccess;
20
+ const entityApiKeysRouter = new Hono();
21
+ /**
22
+ * Refuse requests that authenticated with an entity API key.
23
+ *
24
+ * Letting a key mint or revoke keys would turn a single leaked credential into
25
+ * permanent, self-renewing access. Key lifecycle stays with a human identity:
26
+ * a Firebase token or a personal API key.
27
+ *
28
+ * @returns An error response to return, or null when the caller may proceed
29
+ */
30
+ function assertNotEntityKeyAuth(c) {
31
+ if (c.get("authMethod") === "entity_api_key") {
32
+ return c.json(errorResponse("Entity API keys cannot manage API keys. Sign in or use a personal API key."), 403);
33
+ }
34
+ return null;
35
+ }
36
+ /**
37
+ * Guard against a misconfigured deployment.
38
+ * `apiKeys` is present whenever `apiKeysTable` is configured, which it is here.
39
+ */
40
+ function requireApiKeyHelper(c) {
41
+ if (!entityHelpers.apiKeys) {
42
+ return c.json(errorResponse("Entity API keys are not enabled"), 501);
43
+ }
44
+ return null;
45
+ }
46
+ // GET all API keys for an entity
47
+ entityApiKeysRouter.get("/", zValidator("param", entitySlugParamSchema), async (c) => {
48
+ try {
49
+ const unavailable = requireApiKeyHelper(c);
50
+ if (unavailable)
51
+ return unavailable;
52
+ const { entitySlug } = c.req.valid("param");
53
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canViewApiKeys");
54
+ if (result.error !== undefined) {
55
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
56
+ }
57
+ const keys = await entityHelpers.apiKeys.getKeys(result.entity.id);
58
+ return c.json(successResponse(keys));
59
+ }
60
+ catch (error) {
61
+ console.error("Error listing entity API keys:", error);
62
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
63
+ }
64
+ });
65
+ // POST create an API key -- the only response carrying the plaintext secret
66
+ entityApiKeysRouter.post("/", zValidator("param", entitySlugParamSchema), zValidator("json", entityApiKeyCreateSchema), async (c) => {
67
+ try {
68
+ const unavailable = requireApiKeyHelper(c);
69
+ if (unavailable)
70
+ return unavailable;
71
+ const forbidden = assertNotEntityKeyAuth(c);
72
+ if (forbidden)
73
+ return forbidden;
74
+ const userId = c.get("userId");
75
+ const { entitySlug } = c.req.valid("param");
76
+ const body = c.req.valid("json");
77
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
78
+ if (result.error !== undefined) {
79
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
80
+ }
81
+ const created = await entityHelpers.apiKeys.createKey(result.entity.id, userId, body.key_name);
82
+ return c.json(successResponse(created), 201);
83
+ }
84
+ catch (error) {
85
+ console.error("Error creating entity API key:", error);
86
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
87
+ }
88
+ });
89
+ // PUT rename a key or toggle whether it is active
90
+ entityApiKeysRouter.put("/:keyId", zValidator("param", entityApiKeyIdParamSchema), zValidator("json", entityApiKeyUpdateSchema), async (c) => {
91
+ try {
92
+ const unavailable = requireApiKeyHelper(c);
93
+ if (unavailable)
94
+ return unavailable;
95
+ const forbidden = assertNotEntityKeyAuth(c);
96
+ if (forbidden)
97
+ return forbidden;
98
+ const { entitySlug, keyId } = c.req.valid("param");
99
+ const body = c.req.valid("json");
100
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
101
+ if (result.error !== undefined) {
102
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
103
+ }
104
+ const updated = await entityHelpers.apiKeys.updateKey(result.entity.id, keyId, { keyName: body.key_name, isActive: body.is_active });
105
+ if (!updated) {
106
+ return c.json(errorResponse("API key not found"), 404);
107
+ }
108
+ return c.json(successResponse(updated));
109
+ }
110
+ catch (error) {
111
+ console.error("Error updating entity API key:", error);
112
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
113
+ }
114
+ });
115
+ // DELETE revoke a key permanently
116
+ entityApiKeysRouter.delete("/:keyId", zValidator("param", entityApiKeyIdParamSchema), async (c) => {
117
+ try {
118
+ const unavailable = requireApiKeyHelper(c);
119
+ if (unavailable)
120
+ return unavailable;
121
+ const forbidden = assertNotEntityKeyAuth(c);
122
+ if (forbidden)
123
+ return forbidden;
124
+ const { entitySlug, keyId } = c.req.valid("param");
125
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
126
+ if (result.error !== undefined) {
127
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
128
+ }
129
+ const revoked = await entityHelpers.apiKeys.revokeKey(result.entity.id, keyId);
130
+ if (!revoked) {
131
+ return c.json(errorResponse("API key not found"), 404);
132
+ }
133
+ return c.json(successResponse({ revoked: true }));
134
+ }
135
+ catch (error) {
136
+ console.error("Error revoking entity API key:", error);
137
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
138
+ }
139
+ });
140
+ return entityApiKeysRouter;
141
+ }
142
+ //# sourceMappingURL=entity-api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-api-keys.js","sourceRoot":"","sources":["../../src/routes/entity-api-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview User Invitation Routes
3
+ * @description API routes for managing user's pending invitations
4
+ */
5
+ import { Hono } from "hono";
6
+ import type { ServiceContext } from "../context.js";
7
+ type Variables = {
8
+ userId: string;
9
+ userEmail: string | null;
10
+ };
11
+ export declare function createInvitationsRouter(ctx: ServiceContext): Hono<{
12
+ Variables: Variables;
13
+ }, import("hono/types").BlankSchema, "/">;
14
+ export {};
15
+ //# sourceMappingURL=invitations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invitations.d.ts","sourceRoot":"","sources":["../../src/routes/invitations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,cAAc;eAGT,SAAS;0CAyD1D"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @fileoverview User Invitation Routes
3
+ * @description API routes for managing user's pending invitations
4
+ */
5
+ import { Hono } from "hono";
6
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
7
+ export function createInvitationsRouter(ctx) {
8
+ const helpers = ctx.entityAccess.entityHelpers;
9
+ const invitationsRouter = new Hono();
10
+ /**
11
+ * GET /invitations - List pending invitations for the current user
12
+ */
13
+ invitationsRouter.get("/", async (c) => {
14
+ const userEmail = c.get("userEmail");
15
+ if (!userEmail) {
16
+ return c.json(successResponse([]));
17
+ }
18
+ try {
19
+ const invitations = await helpers.invitations.getUserPendingInvitations(userEmail);
20
+ return c.json(successResponse(invitations));
21
+ }
22
+ catch (error) {
23
+ console.error("Error listing user invitations:", error);
24
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
25
+ }
26
+ });
27
+ /**
28
+ * POST /invitations/:token/accept - Accept an invitation
29
+ */
30
+ invitationsRouter.post("/:token/accept", async (c) => {
31
+ const userId = c.get("userId");
32
+ const token = c.req.param("token");
33
+ try {
34
+ await helpers.invitations.acceptInvitation(token, userId);
35
+ return c.json(successResponse(null));
36
+ }
37
+ catch (error) {
38
+ console.error("Error accepting invitation:", error);
39
+ return c.json(errorResponse(error.message || "Bad request"), 400);
40
+ }
41
+ });
42
+ /**
43
+ * POST /invitations/:token/decline - Decline an invitation
44
+ */
45
+ invitationsRouter.post("/:token/decline", async (c) => {
46
+ const token = c.req.param("token");
47
+ try {
48
+ await helpers.invitations.declineInvitation(token);
49
+ return c.json(successResponse(null));
50
+ }
51
+ catch (error) {
52
+ console.error("Error declining invitation:", error);
53
+ return c.json(errorResponse(error.message || "Bad request"), 400);
54
+ }
55
+ });
56
+ return invitationsRouter;
57
+ }
58
+ //# sourceMappingURL=invitations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invitations.js","sourceRoot":"","sources":["../../src/routes/invitations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,aAAa,GACd,MAAM,qCAAqC,CAAC;AAS7C,MAAM,UAAU,uBAAuB,CAAC,GAAmB;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;IAE/C,MAAM,iBAAiB,GAAG,IAAI,IAAI,EAA4B,CAAC;IAE/D;;OAEG;IACH,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;QACnC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAErC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAqB,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,WAAW,GACf,MAAM,OAAO,CAAC,WAAW,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAqB,WAAW,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,OAAO,CAAC,CAAC,IAAI,CACX,aAAa,CAAC,KAAK,CAAC,OAAO,IAAI,uBAAuB,CAAC,EACvD,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;QACjD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC1D,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAO,IAAI,CAAC,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,IAAI,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;QAClD,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACnD,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAO,IAAI,CAAC,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,IAAI,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Project management routes
3
+ * @description CRUD operations for projects. Each project gets an auto-generated
4
+ * API key on creation. Includes API key retrieval and refresh endpoints.
5
+ */
6
+ import { Hono } from "hono";
7
+ import type { ServiceContext } from "../context.js";
8
+ export declare function createProjectsRouter(ctx: ServiceContext): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
9
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAiB5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,8EAmZvD"}