@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,138 @@
1
+ /**
2
+ * @fileoverview User settings routes
3
+ * @description Manages per-user settings including organization name and path.
4
+ * Uses upsert pattern -- settings are created on first PUT if they don't exist.
5
+ */
6
+ import { Hono } from "hono";
7
+ import { zValidator } from "@hono/zod-validator";
8
+ import { eq } from "drizzle-orm";
9
+ import { settingsUpdateSchema } from "../schemas/index.js";
10
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
11
+ export function createSettingsRouter(ctx) {
12
+ const { db } = ctx;
13
+ const { users, userSettings } = ctx.tables;
14
+ const settingsRouter = new Hono();
15
+ /**
16
+ * Helper to get or create user by Firebase UID
17
+ */
18
+ async function getOrCreateUser(firebaseUid, email) {
19
+ const existing = await db
20
+ .select()
21
+ .from(users)
22
+ .where(eq(users.firebase_uid, firebaseUid));
23
+ if (existing.length > 0) {
24
+ return existing[0];
25
+ }
26
+ const created = await db
27
+ .insert(users)
28
+ .values({
29
+ firebase_uid: firebaseUid,
30
+ email: email ?? null,
31
+ })
32
+ .returning();
33
+ return created[0];
34
+ }
35
+ /**
36
+ * Generate default organization path from firebase UID
37
+ * Uses first 8 characters of the UID (without special characters)
38
+ */
39
+ function generateDefaultOrgPath(firebaseUid) {
40
+ return firebaseUid.replace(/[^a-zA-Z0-9]/g, "").slice(0, 8);
41
+ }
42
+ // GET user settings
43
+ settingsRouter.get("/", async (c) => {
44
+ const authUserId = c.get("userId");
45
+ const authUserEmail = c.get("userEmail");
46
+ const userId = c.req.param("userId");
47
+ if (authUserId !== userId) {
48
+ return c.json(errorResponse("You can only access your own settings"), 403);
49
+ }
50
+ const user = await getOrCreateUser(authUserId, authUserEmail ?? undefined);
51
+ const rows = await db
52
+ .select()
53
+ .from(userSettings)
54
+ .where(eq(userSettings.firebase_uid, user.firebase_uid));
55
+ if (rows.length === 0) {
56
+ // Return default settings with auto-generated org path
57
+ const defaultSettings = {
58
+ id: null,
59
+ firebase_uid: user.firebase_uid,
60
+ organization_name: null,
61
+ organization_path: generateDefaultOrgPath(user.firebase_uid),
62
+ is_default: true,
63
+ created_at: null,
64
+ updated_at: null,
65
+ };
66
+ return c.json(successResponse(defaultSettings));
67
+ }
68
+ const settings = { ...rows[0], is_default: false };
69
+ return c.json(successResponse(settings));
70
+ });
71
+ // PUT create/update settings (upsert)
72
+ settingsRouter.put("/", zValidator("json", settingsUpdateSchema), async (c) => {
73
+ const authUserId = c.get("userId");
74
+ const authUserEmail = c.get("userEmail");
75
+ const userId = c.req.param("userId");
76
+ const body = c.req.valid("json");
77
+ if (authUserId !== userId) {
78
+ return c.json(errorResponse("You can only update your own settings"), 403);
79
+ }
80
+ const user = await getOrCreateUser(authUserId, authUserEmail ?? undefined);
81
+ // Check if settings exist
82
+ const existing = await db
83
+ .select()
84
+ .from(userSettings)
85
+ .where(eq(userSettings.firebase_uid, user.firebase_uid));
86
+ // If changing organization_path, check for duplicates
87
+ if (body.organization_path) {
88
+ const duplicate = await db
89
+ .select()
90
+ .from(userSettings)
91
+ .where(eq(userSettings.organization_path, body.organization_path));
92
+ if (duplicate.length > 0 &&
93
+ (existing.length === 0 ||
94
+ duplicate[0].firebase_uid !== user.firebase_uid)) {
95
+ return c.json(errorResponse("Organization path already taken"), 409);
96
+ }
97
+ }
98
+ if (existing.length === 0) {
99
+ // Create new settings
100
+ const orgPath = body.organization_path || generateDefaultOrgPath(user.firebase_uid);
101
+ // Double-check the auto-generated path isn't taken
102
+ if (!body.organization_path) {
103
+ const autoPathCheck = await db
104
+ .select()
105
+ .from(userSettings)
106
+ .where(eq(userSettings.organization_path, orgPath));
107
+ if (autoPathCheck.length > 0) {
108
+ return c.json(errorResponse("Auto-generated organization path is taken. Please provide a custom organization_path."), 409);
109
+ }
110
+ }
111
+ const rows = await db
112
+ .insert(userSettings)
113
+ .values({
114
+ firebase_uid: user.firebase_uid,
115
+ organization_name: body.organization_name ?? null,
116
+ organization_path: orgPath,
117
+ })
118
+ .returning();
119
+ const created = { ...rows[0], is_default: false };
120
+ return c.json(successResponse(created), 201);
121
+ }
122
+ // Update existing settings
123
+ const current = existing[0];
124
+ const rows = await db
125
+ .update(userSettings)
126
+ .set({
127
+ organization_name: body.organization_name ?? current.organization_name,
128
+ organization_path: body.organization_path ?? current.organization_path,
129
+ updated_at: new Date(),
130
+ })
131
+ .where(eq(userSettings.firebase_uid, user.firebase_uid))
132
+ .returning();
133
+ const updated = { ...rows[0], is_default: false };
134
+ return c.json(successResponse(updated));
135
+ });
136
+ return settingsRouter;
137
+ }
138
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/routes/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Entity cloud storage configuration routes
3
+ * @description Manages GCS/S3 storage configs for entities. Credentials
4
+ * are encrypted at rest using AES-256-CBC. Supports create, update, and delete.
5
+ */
6
+ import { Hono } from "hono";
7
+ import type { ServiceContext } from "../context.js";
8
+ export declare function createStorageRouter(ctx: ServiceContext): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
9
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/routes/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,8EAkQtD"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * @fileoverview Entity cloud storage configuration routes
3
+ * @description Manages GCS/S3 storage configs for entities. Credentials
4
+ * are encrypted at rest using AES-256-CBC. Supports create, update, and delete.
5
+ */
6
+ import { Hono } from "hono";
7
+ import { zValidator } from "@hono/zod-validator";
8
+ import { eq } from "drizzle-orm";
9
+ import { storageConfigCreateSchema, storageConfigUpdateSchema, entitySlugParamSchema, } from "../schemas/index.js";
10
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
11
+ export function createStorageRouter(ctx) {
12
+ const { db } = ctx;
13
+ const { entityStorageConfigs } = ctx.tables;
14
+ const { encryptApiKey } = ctx.encryption;
15
+ const { getActor, getEntityWithPermission, getPermissionErrorStatus } = ctx.entityAccess;
16
+ const storageRouter = new Hono();
17
+ /**
18
+ * Convert database storage config to safe response (no credentials)
19
+ */
20
+ function toSafeConfig(config) {
21
+ return {
22
+ uuid: config.uuid,
23
+ entity_id: config.entity_id,
24
+ provider: config.provider,
25
+ bucket: config.bucket,
26
+ path_prefix: config.path_prefix,
27
+ created_at: config.created_at,
28
+ updated_at: config.updated_at,
29
+ };
30
+ }
31
+ // GET storage config for entity
32
+ storageRouter.get("/", zValidator("param", entitySlugParamSchema), async (c) => {
33
+ try {
34
+ const { entitySlug } = c.req.valid("param");
35
+ const result = await getEntityWithPermission(entitySlug, getActor(c));
36
+ if (result.error !== undefined) {
37
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
38
+ }
39
+ const rows = await db
40
+ .select()
41
+ .from(entityStorageConfigs)
42
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id));
43
+ if (rows.length === 0) {
44
+ return c.json(errorResponse("Storage configuration not found"), 404);
45
+ }
46
+ return c.json(successResponse(toSafeConfig(rows[0])));
47
+ }
48
+ catch (error) {
49
+ console.error("Error getting storage config:", error);
50
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
51
+ }
52
+ });
53
+ // POST create or update storage config (upsert)
54
+ storageRouter.post("/", zValidator("param", entitySlugParamSchema), zValidator("json", storageConfigCreateSchema), async (c) => {
55
+ try {
56
+ const userId = c.get("userId");
57
+ const { entitySlug } = c.req.valid("param");
58
+ const body = c.req.valid("json");
59
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
60
+ if (result.error !== undefined) {
61
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
62
+ }
63
+ // Encrypt credentials
64
+ const credentialsJson = JSON.stringify(body.credentials);
65
+ const { encrypted, iv } = encryptApiKey(credentialsJson);
66
+ // Check if config already exists
67
+ const existing = await db
68
+ .select()
69
+ .from(entityStorageConfigs)
70
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id));
71
+ let rows;
72
+ if (existing.length > 0) {
73
+ // Update existing config
74
+ rows = await db
75
+ .update(entityStorageConfigs)
76
+ .set({
77
+ provider: body.provider,
78
+ bucket: body.bucket,
79
+ path_prefix: body.path_prefix ?? null,
80
+ encrypted_credentials: encrypted,
81
+ encryption_iv: iv,
82
+ updated_at: new Date(),
83
+ })
84
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id))
85
+ .returning();
86
+ }
87
+ else {
88
+ // Create new config
89
+ rows = await db
90
+ .insert(entityStorageConfigs)
91
+ .values({
92
+ entity_id: result.entity.id,
93
+ provider: body.provider,
94
+ bucket: body.bucket,
95
+ path_prefix: body.path_prefix ?? null,
96
+ encrypted_credentials: encrypted,
97
+ encryption_iv: iv,
98
+ created_by: userId,
99
+ })
100
+ .returning();
101
+ }
102
+ return c.json(successResponse(toSafeConfig(rows[0])), existing.length > 0 ? 200 : 201);
103
+ }
104
+ catch (error) {
105
+ console.error("Error creating/updating storage config:", error);
106
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
107
+ }
108
+ });
109
+ // PUT update storage config (partial update)
110
+ storageRouter.put("/", zValidator("param", entitySlugParamSchema), zValidator("json", storageConfigUpdateSchema), async (c) => {
111
+ try {
112
+ const { entitySlug } = c.req.valid("param");
113
+ const body = c.req.valid("json");
114
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
115
+ if (result.error !== undefined) {
116
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
117
+ }
118
+ // Check if config exists
119
+ const existing = await db
120
+ .select()
121
+ .from(entityStorageConfigs)
122
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id));
123
+ if (existing.length === 0) {
124
+ return c.json(errorResponse("Storage configuration not found"), 404);
125
+ }
126
+ const current = existing[0];
127
+ // Prepare update values
128
+ let encryptedCredentials = current.encrypted_credentials;
129
+ let encryptionIv = current.encryption_iv;
130
+ if (body.credentials) {
131
+ const credentialsJson = JSON.stringify(body.credentials);
132
+ const { encrypted, iv } = encryptApiKey(credentialsJson);
133
+ encryptedCredentials = encrypted;
134
+ encryptionIv = iv;
135
+ }
136
+ const rows = await db
137
+ .update(entityStorageConfigs)
138
+ .set({
139
+ bucket: body.bucket ?? current.bucket,
140
+ path_prefix: body.path_prefix !== undefined
141
+ ? body.path_prefix
142
+ : current.path_prefix,
143
+ encrypted_credentials: encryptedCredentials,
144
+ encryption_iv: encryptionIv,
145
+ updated_at: new Date(),
146
+ })
147
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id))
148
+ .returning();
149
+ return c.json(successResponse(toSafeConfig(rows[0])));
150
+ }
151
+ catch (error) {
152
+ console.error("Error updating storage config:", error);
153
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
154
+ }
155
+ });
156
+ // DELETE storage config
157
+ storageRouter.delete("/", zValidator("param", entitySlugParamSchema), async (c) => {
158
+ try {
159
+ const { entitySlug } = c.req.valid("param");
160
+ const result = await getEntityWithPermission(entitySlug, getActor(c), "canManageApiKeys");
161
+ if (result.error !== undefined) {
162
+ return c.json(errorResponse(result.error), getPermissionErrorStatus(result.errorCode));
163
+ }
164
+ const rows = await db
165
+ .delete(entityStorageConfigs)
166
+ .where(eq(entityStorageConfigs.entity_id, result.entity.id))
167
+ .returning();
168
+ if (rows.length === 0) {
169
+ return c.json(errorResponse("Storage configuration not found"), 404);
170
+ }
171
+ return c.json(successResponse(toSafeConfig(rows[0])));
172
+ }
173
+ catch (error) {
174
+ console.error("Error deleting storage config:", error);
175
+ return c.json(errorResponse(error.message || "Internal server error"), 500);
176
+ }
177
+ });
178
+ return storageRouter;
179
+ }
180
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/routes/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Personal API key routes
3
+ * @description CRUD for the personal API keys (`<user prefix>...`) a user can present instead of a
4
+ * Firebase ID token. Keys are scoped to a user (not an entity): a key carries
5
+ * exactly the access its owner has, across every entity they belong to.
6
+ *
7
+ * Two operations hand back a usable secret — create and reveal — and both
8
+ * deliberately require a Firebase ID token. A leaked key can therefore be used
9
+ * to call the API, but not to mint further credentials or read sibling keys.
10
+ */
11
+ import { Hono } from "hono";
12
+ import type { ServiceContext } from "../context.js";
13
+ export declare function createUserApiKeysRouter(ctx: ServiceContext): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
14
+ //# sourceMappingURL=user-api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-api-keys.d.ts","sourceRoot":"","sources":["../../src/routes/user-api-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,cAAc,8EA2U1D"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * @fileoverview Personal API key routes
3
+ * @description CRUD for the personal API keys (`<user prefix>...`) a user can present instead of a
4
+ * Firebase ID token. Keys are scoped to a user (not an entity): a key carries
5
+ * exactly the access its owner has, across every entity they belong to.
6
+ *
7
+ * Two operations hand back a usable secret — create and reveal — and both
8
+ * deliberately require a Firebase ID token. A leaked key can therefore be used
9
+ * to call the API, but not to mint further credentials or read sibling keys.
10
+ */
11
+ import { Hono } from "hono";
12
+ import { zValidator } from "@hono/zod-validator";
13
+ import { eq, and, desc } from "drizzle-orm";
14
+ import { successResponse, errorResponse, } from "@sudobility/shapeshyft_engine/types";
15
+ import { apiKeyIdParamSchema, userApiKeyCreateSchema, userApiKeyUpdateSchema, userIdParamSchema, } from "../schemas/index.js";
16
+ export function createUserApiKeysRouter(ctx) {
17
+ const { db } = ctx;
18
+ const { userApiKeys } = ctx.tables;
19
+ const { generateUserApiKey, hashUserApiKey, encryptUserApiKey, decryptUserApiKey, } = ctx.userApiKeys;
20
+ const { invalidateUserApiKeyCache } = ctx.userApiKeyCache;
21
+ const userApiKeysRouter = new Hono();
22
+ function toSafe(row) {
23
+ return {
24
+ uuid: row.uuid,
25
+ firebase_uid: row.firebase_uid,
26
+ key_name: row.key_name,
27
+ key_prefix: row.key_prefix,
28
+ is_active: row.is_active,
29
+ last_used_at: row.last_used_at?.toISOString() ?? null,
30
+ created_at: row.created_at?.toISOString() ?? null,
31
+ updated_at: row.updated_at?.toISOString() ?? null,
32
+ };
33
+ }
34
+ /**
35
+ * Verify the path userId matches the authenticated user.
36
+ * Returns an error message when it does not.
37
+ */
38
+ function checkOwnership(c, userId) {
39
+ const authUserId = c.get("userId");
40
+ return authUserId === userId
41
+ ? null
42
+ : "You can only manage your own API keys";
43
+ }
44
+ /** Operations that yield a usable secret require a real Firebase token. */
45
+ function requireFirebaseAuth(c) {
46
+ return c.get("authMethod") === "api_key"
47
+ ? "This operation requires a Firebase ID token. An API key cannot create or reveal API keys."
48
+ : null;
49
+ }
50
+ // =============================================================================
51
+ // Routes
52
+ // =============================================================================
53
+ /**
54
+ * GET /users/:userId/api-keys
55
+ * List the caller's API keys. Secrets are never included.
56
+ */
57
+ userApiKeysRouter.get("/", zValidator("param", userIdParamSchema), async (c) => {
58
+ try {
59
+ const { userId } = c.req.valid("param");
60
+ const ownershipError = checkOwnership(c, userId);
61
+ if (ownershipError)
62
+ return c.json(errorResponse(ownershipError), 403);
63
+ const rows = await db
64
+ .select()
65
+ .from(userApiKeys)
66
+ .where(eq(userApiKeys.firebase_uid, userId))
67
+ .orderBy(desc(userApiKeys.created_at));
68
+ return c.json(successResponse(rows.map(toSafe)));
69
+ }
70
+ catch (error) {
71
+ console.error("Error listing user API keys:", error);
72
+ const message = error instanceof Error ? error.message : "Internal server error";
73
+ return c.json(errorResponse(message), 500);
74
+ }
75
+ });
76
+ /**
77
+ * POST /users/:userId/api-keys
78
+ * Create a key. The full value is returned once, here.
79
+ * Requires a Firebase ID token.
80
+ */
81
+ userApiKeysRouter.post("/", zValidator("param", userIdParamSchema), zValidator("json", userApiKeyCreateSchema), async (c) => {
82
+ try {
83
+ const { userId } = c.req.valid("param");
84
+ const { key_name } = c.req.valid("json");
85
+ const ownershipError = checkOwnership(c, userId);
86
+ if (ownershipError)
87
+ return c.json(errorResponse(ownershipError), 403);
88
+ const authError = requireFirebaseAuth(c);
89
+ if (authError)
90
+ return c.json(errorResponse(authError), 403);
91
+ const { key, prefix } = generateUserApiKey();
92
+ const { encrypted, iv } = encryptUserApiKey(key);
93
+ const rows = await db
94
+ .insert(userApiKeys)
95
+ .values({
96
+ firebase_uid: userId,
97
+ key_name,
98
+ key_hash: hashUserApiKey(key),
99
+ key_prefix: prefix,
100
+ encrypted_key: encrypted,
101
+ encryption_iv: iv,
102
+ })
103
+ .returning();
104
+ const created = {
105
+ ...toSafe(rows[0]),
106
+ api_key: key,
107
+ };
108
+ return c.json(successResponse(created), 201);
109
+ }
110
+ catch (error) {
111
+ console.error("Error creating user API key:", error);
112
+ const message = error instanceof Error ? error.message : "Bad request";
113
+ return c.json(errorResponse(message), 400);
114
+ }
115
+ });
116
+ /**
117
+ * GET /users/:userId/api-keys/:keyId
118
+ * Metadata for one key. The secret is not included.
119
+ */
120
+ userApiKeysRouter.get("/:keyId", zValidator("param", apiKeyIdParamSchema), async (c) => {
121
+ try {
122
+ const { userId, keyId } = c.req.valid("param");
123
+ const ownershipError = checkOwnership(c, userId);
124
+ if (ownershipError)
125
+ return c.json(errorResponse(ownershipError), 403);
126
+ const rows = await db
127
+ .select()
128
+ .from(userApiKeys)
129
+ .where(and(eq(userApiKeys.firebase_uid, userId), eq(userApiKeys.uuid, keyId)));
130
+ if (rows.length === 0) {
131
+ return c.json(errorResponse("API key not found"), 404);
132
+ }
133
+ return c.json(successResponse(toSafe(rows[0])));
134
+ }
135
+ catch (error) {
136
+ console.error("Error getting user API key:", error);
137
+ const message = error instanceof Error ? error.message : "Internal server error";
138
+ return c.json(errorResponse(message), 500);
139
+ }
140
+ });
141
+ /**
142
+ * GET /users/:userId/api-keys/:keyId/reveal
143
+ * Return the full key so its owner can copy it again.
144
+ * Requires a Firebase ID token.
145
+ */
146
+ userApiKeysRouter.get("/:keyId/reveal", zValidator("param", apiKeyIdParamSchema), async (c) => {
147
+ try {
148
+ const { userId, keyId } = c.req.valid("param");
149
+ const ownershipError = checkOwnership(c, userId);
150
+ if (ownershipError)
151
+ return c.json(errorResponse(ownershipError), 403);
152
+ const authError = requireFirebaseAuth(c);
153
+ if (authError)
154
+ return c.json(errorResponse(authError), 403);
155
+ const rows = await db
156
+ .select()
157
+ .from(userApiKeys)
158
+ .where(and(eq(userApiKeys.firebase_uid, userId), eq(userApiKeys.uuid, keyId)));
159
+ if (rows.length === 0) {
160
+ return c.json(errorResponse("API key not found"), 404);
161
+ }
162
+ const row = rows[0];
163
+ const apiKey = decryptUserApiKey(row.encrypted_key, row.encryption_iv);
164
+ return c.json(successResponse({ api_key: apiKey }));
165
+ }
166
+ catch (error) {
167
+ console.error("Error revealing user API key:", error);
168
+ const message = error instanceof Error ? error.message : "Internal server error";
169
+ return c.json(errorResponse(message), 500);
170
+ }
171
+ });
172
+ /**
173
+ * PUT /users/:userId/api-keys/:keyId
174
+ * Rename a key or toggle it active. Deactivating takes effect immediately.
175
+ */
176
+ userApiKeysRouter.put("/:keyId", zValidator("param", apiKeyIdParamSchema), zValidator("json", userApiKeyUpdateSchema), async (c) => {
177
+ try {
178
+ const { userId, keyId } = c.req.valid("param");
179
+ const body = c.req.valid("json");
180
+ const ownershipError = checkOwnership(c, userId);
181
+ if (ownershipError)
182
+ return c.json(errorResponse(ownershipError), 403);
183
+ const existing = await db
184
+ .select()
185
+ .from(userApiKeys)
186
+ .where(and(eq(userApiKeys.firebase_uid, userId), eq(userApiKeys.uuid, keyId)));
187
+ if (existing.length === 0) {
188
+ return c.json(errorResponse("API key not found"), 404);
189
+ }
190
+ const rows = await db
191
+ .update(userApiKeys)
192
+ .set({
193
+ key_name: body.key_name ?? existing[0].key_name,
194
+ is_active: body.is_active ?? existing[0].is_active,
195
+ updated_at: new Date(),
196
+ })
197
+ .where(eq(userApiKeys.uuid, keyId))
198
+ .returning();
199
+ // Drop the cached identity so a deactivation is not honored late.
200
+ invalidateUserApiKeyCache(existing[0].key_hash);
201
+ return c.json(successResponse(toSafe(rows[0])));
202
+ }
203
+ catch (error) {
204
+ console.error("Error updating user API key:", error);
205
+ const message = error instanceof Error ? error.message : "Bad request";
206
+ return c.json(errorResponse(message), 400);
207
+ }
208
+ });
209
+ /**
210
+ * DELETE /users/:userId/api-keys/:keyId
211
+ * Permanently revoke a key.
212
+ */
213
+ userApiKeysRouter.delete("/:keyId", zValidator("param", apiKeyIdParamSchema), async (c) => {
214
+ try {
215
+ const { userId, keyId } = c.req.valid("param");
216
+ const ownershipError = checkOwnership(c, userId);
217
+ if (ownershipError)
218
+ return c.json(errorResponse(ownershipError), 403);
219
+ const rows = await db
220
+ .delete(userApiKeys)
221
+ .where(and(eq(userApiKeys.firebase_uid, userId), eq(userApiKeys.uuid, keyId)))
222
+ .returning();
223
+ if (rows.length === 0) {
224
+ return c.json(errorResponse("API key not found"), 404);
225
+ }
226
+ invalidateUserApiKeyCache(rows[0].key_hash);
227
+ return c.json(successResponse(toSafe(rows[0])));
228
+ }
229
+ catch (error) {
230
+ console.error("Error deleting user API key:", error);
231
+ const message = error instanceof Error ? error.message : "Bad request";
232
+ return c.json(errorResponse(message), 400);
233
+ }
234
+ });
235
+ return userApiKeysRouter;
236
+ }
237
+ //# sourceMappingURL=user-api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-api-keys.js","sourceRoot":"","sources":["../../src/routes/user-api-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview User routes
3
+ */
4
+ import { Hono } from "hono";
5
+ import type { ServiceContext } from "../context.js";
6
+ export declare function createUsersRouter(ctx: ServiceContext): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
7
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,8EAuHpD"}