@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.
- package/CLAUDE.md +35 -0
- package/README.md +17 -0
- package/dist/context.d.ts +62 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +55 -0
- package/dist/context.js.map +1 -0
- package/dist/contracts.d.ts +110 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +7 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-key.d.ts +22 -0
- package/dist/lib/api-key.d.ts.map +1 -0
- package/dist/lib/api-key.js +87 -0
- package/dist/lib/api-key.js.map +1 -0
- package/dist/lib/encryption.d.ts +22 -0
- package/dist/lib/encryption.d.ts.map +1 -0
- package/dist/lib/encryption.js +41 -0
- package/dist/lib/encryption.js.map +1 -0
- package/dist/lib/entity-api-key.d.ts +21 -0
- package/dist/lib/entity-api-key.d.ts.map +1 -0
- package/dist/lib/entity-api-key.js +54 -0
- package/dist/lib/entity-api-key.js.map +1 -0
- package/dist/lib/entity-helpers.d.ts +90 -0
- package/dist/lib/entity-helpers.d.ts.map +1 -0
- package/dist/lib/entity-helpers.js +136 -0
- package/dist/lib/entity-helpers.js.map +1 -0
- package/dist/lib/money.d.ts +7 -0
- package/dist/lib/money.d.ts.map +1 -0
- package/dist/lib/money.js +9 -0
- package/dist/lib/money.js.map +1 -0
- package/dist/lib/public-project.d.ts +14 -0
- package/dist/lib/public-project.d.ts.map +1 -0
- package/dist/lib/public-project.js +17 -0
- package/dist/lib/public-project.js.map +1 -0
- package/dist/lib/user-api-key-cache.d.ts +35 -0
- package/dist/lib/user-api-key-cache.d.ts.map +1 -0
- package/dist/lib/user-api-key-cache.js +99 -0
- package/dist/lib/user-api-key-cache.js.map +1 -0
- package/dist/lib/user-api-key.d.ts +46 -0
- package/dist/lib/user-api-key.d.ts.map +1 -0
- package/dist/lib/user-api-key.js +102 -0
- package/dist/lib/user-api-key.js.map +1 -0
- package/dist/middleware/firebaseAuth.d.ts +34 -0
- package/dist/middleware/firebaseAuth.d.ts.map +1 -0
- package/dist/middleware/firebaseAuth.js +133 -0
- package/dist/middleware/firebaseAuth.js.map +1 -0
- package/dist/middleware/rateLimit.d.ts +29 -0
- package/dist/middleware/rateLimit.d.ts.map +1 -0
- package/dist/middleware/rateLimit.js +85 -0
- package/dist/middleware/rateLimit.js.map +1 -0
- package/dist/middleware/subscription.d.ts +8 -0
- package/dist/middleware/subscription.d.ts.map +1 -0
- package/dist/middleware/subscription.js +19 -0
- package/dist/middleware/subscription.js.map +1 -0
- package/dist/routes/ai.d.ts +10 -0
- package/dist/routes/ai.d.ts.map +1 -0
- package/dist/routes/ai.js +698 -0
- package/dist/routes/ai.js.map +1 -0
- package/dist/routes/analytics.d.ts +9 -0
- package/dist/routes/analytics.d.ts.map +1 -0
- package/dist/routes/analytics.js +192 -0
- package/dist/routes/analytics.js.map +1 -0
- package/dist/routes/endpoints.d.ts +10 -0
- package/dist/routes/endpoints.d.ts.map +1 -0
- package/dist/routes/endpoints.js +255 -0
- package/dist/routes/endpoints.js.map +1 -0
- package/dist/routes/entities.d.ts +15 -0
- package/dist/routes/entities.d.ts.map +1 -0
- package/dist/routes/entities.js +332 -0
- package/dist/routes/entities.js.map +1 -0
- package/dist/routes/entity-api-keys.d.ts +17 -0
- package/dist/routes/entity-api-keys.d.ts.map +1 -0
- package/dist/routes/entity-api-keys.js +142 -0
- package/dist/routes/entity-api-keys.js.map +1 -0
- package/dist/routes/invitations.d.ts +15 -0
- package/dist/routes/invitations.d.ts.map +1 -0
- package/dist/routes/invitations.js +58 -0
- package/dist/routes/invitations.js.map +1 -0
- package/dist/routes/projects.d.ts +9 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +241 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/providers.d.ts +9 -0
- package/dist/routes/providers.d.ts.map +1 -0
- package/dist/routes/providers.js +89 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/ratelimits.d.ts +9 -0
- package/dist/routes/ratelimits.d.ts.map +1 -0
- package/dist/routes/ratelimits.js +171 -0
- package/dist/routes/ratelimits.js.map +1 -0
- package/dist/routes/settings.d.ts +9 -0
- package/dist/routes/settings.d.ts.map +1 -0
- package/dist/routes/settings.js +138 -0
- package/dist/routes/settings.js.map +1 -0
- package/dist/routes/storage.d.ts +9 -0
- package/dist/routes/storage.d.ts.map +1 -0
- package/dist/routes/storage.js +180 -0
- package/dist/routes/storage.js.map +1 -0
- package/dist/routes/user-api-keys.d.ts +14 -0
- package/dist/routes/user-api-keys.d.ts.map +1 -0
- package/dist/routes/user-api-keys.js +237 -0
- package/dist/routes/user-api-keys.js.map +1 -0
- package/dist/routes/users.d.ts +7 -0
- package/dist/routes/users.d.ts.map +1 -0
- package/dist/routes/users.js +102 -0
- package/dist/routes/users.js.map +1 -0
- package/dist/schema/init.d.ts +12 -0
- package/dist/schema/init.d.ts.map +1 -0
- package/dist/schema/init.js +404 -0
- package/dist/schema/init.js.map +1 -0
- package/dist/schema/tables.d.ts +2110 -0
- package/dist/schema/tables.d.ts.map +1 -0
- package/dist/schema/tables.js +251 -0
- package/dist/schema/tables.js.map +1 -0
- package/dist/schemas/index.d.ts +671 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +299 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/service.d.ts +41 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +70 -0
- package/dist/service.js.map +1 -0
- 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"}
|