profclaw 0.0.1-beta.1 → 0.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/adapters/openclaw.js +1 -1
- package/dist/agents/executor.js +38 -6
- package/dist/auth/auth-service.js +8 -6
- package/dist/auth/device-identity.js +7 -5
- package/dist/auth/github-oauth.js +3 -1
- package/dist/auth/pairing-codes.js +6 -4
- package/dist/browser/service.js +5 -3
- package/dist/chat/execution/guardrails.js +3 -1
- package/dist/chat/execution/workflows/executor.js +4 -2
- package/dist/chat/memory.js +3 -1
- package/dist/chat/proactive/index.js +13 -11
- package/dist/chat/tools.js +8 -7
- package/dist/cli/commands/auth.js +22 -13
- package/dist/cli/commands/onboard.js +248 -59
- package/dist/cli/commands/setup.js +180 -104
- package/dist/cron/issue-poller.js +1 -1
- package/dist/hooks/agent-webhook.js +10 -7
- package/dist/hooks/prompt-submit.js +5 -6
- package/dist/hooks/session-end.js +10 -6
- package/dist/hooks/tool-use.js +9 -6
- package/dist/integrations/github-ticket-sync.js +8 -6
- package/dist/integrations/github.js +8 -6
- package/dist/integrations/jira.js +5 -3
- package/dist/mcp/server.js +12 -9
- package/dist/memory/experience-store.js +15 -14
- package/dist/notifications/slack.js +4 -2
- package/dist/providers/types.d.ts +2 -2
- package/dist/queue/failure-handler.js +15 -13
- package/dist/queue/index.js +6 -4
- package/dist/queue/memory-queue.js +23 -27
- package/dist/queue/task-queue.js +18 -22
- package/dist/routes/agents.js +3 -1
- package/dist/routes/auth.js +11 -9
- package/dist/routes/devices.js +17 -15
- package/dist/routes/gateway.js +3 -1
- package/dist/routes/hooks.js +7 -5
- package/dist/routes/import.js +10 -8
- package/dist/routes/labels.js +11 -9
- package/dist/routes/oobe.js +8 -6
- package/dist/routes/openapi.js +1 -1
- package/dist/routes/projects.js +27 -25
- package/dist/routes/settings.js +7 -5
- package/dist/routes/setup.js +12 -11
- package/dist/routes/slack.js +28 -27
- package/dist/routes/stats.js +6 -4
- package/dist/routes/summaries.js +4 -3
- package/dist/routes/sync.js +7 -5
- package/dist/routes/tasks.js +10 -8
- package/dist/routes/tickets.js +26 -26
- package/dist/routes/tokens.js +5 -3
- package/dist/routes/users.js +14 -12
- package/dist/routes/webhooks.js +5 -3
- package/dist/settings/index.js +3 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +9 -4
- package/dist/storage/libsql.js +29 -21
- package/dist/storage/schema.d.ts +107 -46
- package/dist/summaries/storage.js +3 -1
- package/dist/tickets/index.js +10 -8
- package/dist/utils/circuit-breaker.js +10 -5
- package/dist/utils/logger.d.ts +5 -1
- package/dist/utils/logger.js +23 -7
- package/package.json +4 -3
- package/ui/dist/assets/{ActivityView-CkPgKhwm.js → ActivityView-DIPQSJ_d.js} +1 -1
- package/ui/dist/assets/{AgentList-C3SVdeEz.js → AgentList-CqyaYrcq.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-DVU--vlP.js → AnalyticsDashboard-C-mjuGHT.js} +1 -1
- package/ui/dist/assets/{AreaChart-B5qMEGWj.js → AreaChart-CfYWmbtr.js} +1 -1
- package/ui/dist/assets/{CartesianChart-B50bcUJi.js → CartesianChart-BaQ3It0c.js} +1 -1
- package/ui/dist/assets/{ChatView-BZFJs7w_.js → ChatView-DxxQy6pl.js} +1 -1
- package/ui/dist/assets/CostsDashboard-CDBBcGkg.js +1 -0
- package/ui/dist/assets/{EstimateSelect-CLpB4NQO.js → EstimateSelect-CDjf5qKl.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CBzBY9a0.js → FloatingChatbot-CZHjvJIe.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DsbdPa6W.js → InviteCodeManagement-DTm-IPTm.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-BEM3tFXg.js → ProjectDetail-DlYUcOss.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-CN1FmFAk.js → ProjectIcon-BMRpnM04.js} +1 -1
- package/ui/dist/assets/{ProjectList-DSDaNhxQ.js → ProjectList-D85TN0i0.js} +1 -1
- package/ui/dist/assets/{Settings-dPVcqC_d.js → Settings-CgPqzUvj.js} +3 -3
- package/ui/dist/assets/{StatusIndicator-DA3NAo_b.js → StatusIndicator-yig0uZEA.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-Bjnf9lT8.js → SummaryDetail-CwLAfHgJ.js} +1 -1
- package/ui/dist/assets/{SummaryList-ENwKDBKW.js → SummaryList-BvS5Idnu.js} +1 -1
- package/ui/dist/assets/{TaskDetail-DnwG6MzB.js → TaskDetail-zarC1fOt.js} +1 -1
- package/ui/dist/assets/{TaskList-D9Ug_HiV.js → TaskList-CyJq3ANE.js} +1 -1
- package/ui/dist/assets/{TicketBoard-CviH1571.js → TicketBoard-BlWr3-iH.js} +1 -1
- package/ui/dist/assets/{TicketDetail-8Jk8O-33.js → TicketDetail-DmqWKj2W.js} +1 -1
- package/ui/dist/assets/{TicketList-B-iV4rRA.js → TicketList-Scj4pMWa.js} +1 -1
- package/ui/dist/assets/{UserManagement-CPZ8s7s2.js → UserManagement-BH7uG7dw.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-BUyOOWDI.js → ViewSwitcher-3HzZUdWn.js} +1 -1
- package/ui/dist/assets/{alert-dialog-BOmnTkN-.js → alert-dialog-DWPb2IfQ.js} +1 -1
- package/ui/dist/assets/{archive-D5my9zOG.js → archive-CGck7gxR.js} +1 -1
- package/ui/dist/assets/{badge-B4ov81_m.js → badge-DEmc3Z_l.js} +1 -1
- package/ui/dist/assets/{brain-C53ElFLD.js → brain-CfFdLVqb.js} +1 -1
- package/ui/dist/assets/{bug-D0TJoCYn.js → bug-DqSGPUUE.js} +1 -1
- package/ui/dist/assets/{calendar-BkWIhKa1.js → calendar-BuZ4zbPW.js} +1 -1
- package/ui/dist/assets/{chevron-up-BRTtndUZ.js → chevron-up-DcJ4LL_N.js} +1 -1
- package/ui/dist/assets/{circle-x-BN89YhbS.js → circle-x-C78PNZjF.js} +1 -1
- package/ui/dist/assets/{constants-fc7TFI7u.js → constants-DhDjZe4P.js} +1 -1
- package/ui/dist/assets/{cpu-B41x1-vV.js → cpu-Ck6AoG8c.js} +1 -1
- package/ui/dist/assets/{database-D9Cnfmzj.js → database-CA2w8Lvt.js} +1 -1
- package/ui/dist/assets/{dialog-DrWB4EYD.js → dialog-BOdGWhgE.js} +1 -1
- package/ui/dist/assets/{ellipsis-NuUWekvu.js → ellipsis-FhHKRbfl.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-BueMfuCw.js → ellipsis-vertical-CO0UqE4-.js} +1 -1
- package/ui/dist/assets/{file-code-HR9829Jc.js → file-code-ChnhYYj1.js} +1 -1
- package/ui/dist/assets/{folder-open-C_7oYEqe.js → folder-open-CHwA1-ve.js} +1 -1
- package/ui/dist/assets/{funnel-B5gmNXGf.js → funnel-ByEjRFNB.js} +1 -1
- package/ui/dist/assets/{git-branch-BRMiJmV3.js → git-branch-GTOPQgU4.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-CXOUQeJI.js → git-commit-horizontal-F5M84Kut.js} +1 -1
- package/ui/dist/assets/{globe-CCspjvus.js → globe-CQWfr7hT.js} +1 -1
- package/ui/dist/assets/{hash-g3102kPC.js → hash-nKC9gtLg.js} +1 -1
- package/ui/dist/assets/{history-CNqcBBrV.js → history-DfFSA9xJ.js} +1 -1
- package/ui/dist/assets/{index-kb4AJXUB.js → index--JkIxVXb.js} +3 -3
- package/ui/dist/assets/index-Ca3vk7Gq.js +1 -0
- package/ui/dist/assets/{index-C9jNQXzL.js → index-DHGvP9mp.js} +1 -1
- package/ui/dist/assets/index-DeI8lKRR.js +1 -0
- package/ui/dist/assets/{index-DURTouJI.js → index-Z4-RtZcs.js} +1 -1
- package/ui/dist/assets/{index-CEZ6R2Uw.js → index-a4Fxq0Hb.js} +1 -1
- package/ui/dist/assets/{layers-CLXiHN6o.js → layers-DFeLExSa.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-B07MFhBs.js → layout-dashboard-WmgjMhWF.js} +1 -1
- package/ui/dist/assets/{lightbulb-B2dgG5ks.js → lightbulb-Bo8hEr7B.js} +1 -1
- package/ui/dist/assets/{link-2-BxNmr9hL.js → link-2-YqrpQXBH.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-CjU6hBcW.js → markdown-renderer-Croje6Xe.js} +1 -1
- package/ui/dist/assets/{message-square-Bf2-CVbt.js → message-square-CD0H5hot.js} +1 -1
- package/ui/dist/assets/{pencil-D096Ey62.js → pencil-DpFnj5dn.js} +1 -1
- package/ui/dist/assets/{play-DfdcSI3x.js → play-DVgea_jT.js} +1 -1
- package/ui/dist/assets/{popover-BV0QJDQq.js → popover-JXecfWG5.js} +1 -1
- package/ui/dist/assets/{progress-DjPEDJfI.js → progress-C1ghf1Fu.js} +1 -1
- package/ui/dist/assets/{rocket-CPsTc-5G.js → rocket-BFxPYGx9.js} +1 -1
- package/ui/dist/assets/{select-LsO16slr.js → select-MADP8m6Q.js} +1 -1
- package/ui/dist/assets/{send-BDYBZDUZ.js → send-eYnW_7n-.js} +1 -1
- package/ui/dist/assets/{server-B3k6noce.js → server-CPMaysH8.js} +1 -1
- package/ui/dist/assets/{settings-2-Cu4xTjhG.js → settings-2-scXUOuE_.js} +1 -1
- package/ui/dist/assets/{sheet-BScLnPKX.js → sheet-r6NSOxi-.js} +1 -1
- package/ui/dist/assets/{shield-check-CQqkwufI.js → shield-check-PEr7nmVw.js} +1 -1
- package/ui/dist/assets/{shield-off-ZFruH9KO.js → shield-off-CLtXio62.js} +1 -1
- package/ui/dist/assets/{skeleton-CtkIA_MU.js → skeleton-C9oEzNlU.js} +1 -1
- package/ui/dist/assets/{smartphone-DnoksVkc.js → smartphone-DusFfY0U.js} +1 -1
- package/ui/dist/assets/{square-uD9ZHMfW.js → square-e1yxB2eR.js} +1 -1
- package/ui/dist/assets/{switch-MQPnwGJK.js → switch-tNs0n-kz.js} +1 -1
- package/ui/dist/assets/{table-B8cqlywA.js → table-CXxtLicg.js} +1 -1
- package/ui/dist/assets/{tag-wEJQRWlV.js → tag-tAwMmQ9G.js} +1 -1
- package/ui/dist/assets/{textarea-D5LJCOGl.js → textarea-BjiEeIWh.js} +1 -1
- package/ui/dist/assets/{timer-mbGHegmr.js → timer-Vel1N3RP.js} +1 -1
- package/ui/dist/assets/{tooltip-Df1CunSp.js → tooltip-ZMwtfr1J.js} +1 -1
- package/ui/dist/assets/{trash-2-B4oAXsX-.js → trash-2-eM-CNwsZ.js} +1 -1
- package/ui/dist/assets/{trending-up-BGWxvlmZ.js → trending-up-BGafmjRo.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-CZy4xvL3.js → wand-sparkles-DPvcd9Pi.js} +1 -1
- package/ui/dist/assets/{wrench-ByZkjO6m.js → wrench-B8s3zYVV.js} +1 -1
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/CostsDashboard-ChfH8BlG.js +0 -1
- package/ui/dist/assets/index-27mTPKuh.js +0 -1
- package/ui/dist/assets/index-BMx3fH-e.js +0 -1
package/dist/routes/import.js
CHANGED
|
@@ -13,7 +13,9 @@ import { validateGitHubToken, listGitHubProjects, listGitHubRepos, getGitHubProj
|
|
|
13
13
|
import { getCookie } from 'hono/cookie';
|
|
14
14
|
import { validateSession } from '../auth/auth-service.js';
|
|
15
15
|
import { createProject, createProjectExternalLink, createSprint } from '../projects/index.js';
|
|
16
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
16
17
|
export const importRoutes = new Hono();
|
|
18
|
+
const log = createContextualLogger('ImportRoutes');
|
|
17
19
|
// Token storage helpers
|
|
18
20
|
async function storeGitHubToken(token, tokenType, username, scopes) {
|
|
19
21
|
const db = getDb();
|
|
@@ -119,7 +121,7 @@ importRoutes.post('/github/validate-token', async (c) => {
|
|
|
119
121
|
});
|
|
120
122
|
}
|
|
121
123
|
catch (error) {
|
|
122
|
-
|
|
124
|
+
log.error('Token validation error', error instanceof Error ? error : new Error(String(error)));
|
|
123
125
|
return c.json({
|
|
124
126
|
valid: false,
|
|
125
127
|
error: error instanceof Error ? error.message : 'Validation failed',
|
|
@@ -149,7 +151,7 @@ importRoutes.get('/github/status', async (c) => {
|
|
|
149
151
|
});
|
|
150
152
|
}
|
|
151
153
|
catch (error) {
|
|
152
|
-
|
|
154
|
+
log.error('Status check error', error instanceof Error ? error : new Error(String(error)));
|
|
153
155
|
return c.json({
|
|
154
156
|
connected: false,
|
|
155
157
|
error: error instanceof Error ? error.message : 'Status check failed',
|
|
@@ -176,7 +178,7 @@ importRoutes.get('/github/projects', async (c) => {
|
|
|
176
178
|
});
|
|
177
179
|
}
|
|
178
180
|
catch (error) {
|
|
179
|
-
|
|
181
|
+
log.error('List projects error', error instanceof Error ? error : new Error(String(error)));
|
|
180
182
|
return c.json({
|
|
181
183
|
error: error instanceof Error ? error.message : 'Failed to list projects',
|
|
182
184
|
}, 500);
|
|
@@ -199,7 +201,7 @@ importRoutes.get('/github/projects/:projectId/preview', async (c) => {
|
|
|
199
201
|
return c.json(preview);
|
|
200
202
|
}
|
|
201
203
|
catch (error) {
|
|
202
|
-
|
|
204
|
+
log.error('Project preview error', error instanceof Error ? error : new Error(String(error)));
|
|
203
205
|
return c.json({
|
|
204
206
|
error: error instanceof Error ? error.message : 'Failed to get project preview',
|
|
205
207
|
}, 500);
|
|
@@ -322,7 +324,7 @@ importRoutes.post('/github/projects/:projectId/dry-run', async (c) => {
|
|
|
322
324
|
});
|
|
323
325
|
}
|
|
324
326
|
catch (error) {
|
|
325
|
-
|
|
327
|
+
log.error('Dry run error', error instanceof Error ? error : new Error(String(error)));
|
|
326
328
|
return c.json({
|
|
327
329
|
error: error instanceof Error ? error.message : 'Dry run failed',
|
|
328
330
|
}, 500);
|
|
@@ -463,7 +465,7 @@ importRoutes.post('/github/projects/:projectId/execute', async (c) => {
|
|
|
463
465
|
});
|
|
464
466
|
}
|
|
465
467
|
catch (error) {
|
|
466
|
-
|
|
468
|
+
log.error('Execute error', error instanceof Error ? error : new Error(String(error)));
|
|
467
469
|
// Check for unique constraint violation
|
|
468
470
|
if (error instanceof Error && error.message.includes('UNIQUE constraint failed')) {
|
|
469
471
|
return c.json({
|
|
@@ -498,7 +500,7 @@ importRoutes.get('/github/repos', async (c) => {
|
|
|
498
500
|
});
|
|
499
501
|
}
|
|
500
502
|
catch (error) {
|
|
501
|
-
|
|
503
|
+
log.error('List repos error', error instanceof Error ? error : new Error(String(error)));
|
|
502
504
|
return c.json({
|
|
503
505
|
error: error instanceof Error ? error.message : 'Failed to list repositories',
|
|
504
506
|
}, 500);
|
|
@@ -520,7 +522,7 @@ importRoutes.delete('/github/disconnect', async (c) => {
|
|
|
520
522
|
});
|
|
521
523
|
}
|
|
522
524
|
catch (error) {
|
|
523
|
-
|
|
525
|
+
log.error('Disconnect error', error instanceof Error ? error : new Error(String(error)));
|
|
524
526
|
return c.json({
|
|
525
527
|
error: error instanceof Error ? error.message : 'Disconnect failed',
|
|
526
528
|
}, 500);
|
package/dist/routes/labels.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import { Hono } from 'hono';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { createLabel, getLabel, listLabels, updateLabel, deleteLabel, getTicketLabels, addLabelToTicket, removeLabelFromTicket, setTicketLabels, } from '../labels/index.js';
|
|
9
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
9
10
|
export const labelsRoutes = new Hono();
|
|
11
|
+
const log = createContextualLogger('LabelsRoutes');
|
|
10
12
|
function getErrorMessage(error) {
|
|
11
13
|
return error instanceof Error ? error.message : undefined;
|
|
12
14
|
}
|
|
@@ -56,7 +58,7 @@ labelsRoutes.get('/projects/:projectId/labels', async (c) => {
|
|
|
56
58
|
});
|
|
57
59
|
}
|
|
58
60
|
catch (error) {
|
|
59
|
-
|
|
61
|
+
log.error('List error', error instanceof Error ? error : new Error(String(error)));
|
|
60
62
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to list labels' }, 500);
|
|
61
63
|
}
|
|
62
64
|
});
|
|
@@ -86,7 +88,7 @@ labelsRoutes.post('/projects/:projectId/labels', async (c) => {
|
|
|
86
88
|
return c.json(label, 201);
|
|
87
89
|
}
|
|
88
90
|
catch (error) {
|
|
89
|
-
|
|
91
|
+
log.error('Create error', error instanceof Error ? error : new Error(String(error)));
|
|
90
92
|
if (getErrorMessage(error)?.includes('UNIQUE constraint')) {
|
|
91
93
|
return c.json({ error: 'A label with this name already exists' }, 409);
|
|
92
94
|
}
|
|
@@ -107,7 +109,7 @@ labelsRoutes.get('/labels/:id', async (c) => {
|
|
|
107
109
|
return c.json(label);
|
|
108
110
|
}
|
|
109
111
|
catch (error) {
|
|
110
|
-
|
|
112
|
+
log.error('Get error', error instanceof Error ? error : new Error(String(error)));
|
|
111
113
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to get label' }, 500);
|
|
112
114
|
}
|
|
113
115
|
});
|
|
@@ -137,7 +139,7 @@ labelsRoutes.patch('/labels/:id', async (c) => {
|
|
|
137
139
|
return c.json(label);
|
|
138
140
|
}
|
|
139
141
|
catch (error) {
|
|
140
|
-
|
|
142
|
+
log.error('Update error', error instanceof Error ? error : new Error(String(error)));
|
|
141
143
|
if (getErrorMessage(error)?.includes('not found')) {
|
|
142
144
|
return c.json({ error: 'Label not found' }, 404);
|
|
143
145
|
}
|
|
@@ -155,7 +157,7 @@ labelsRoutes.delete('/labels/:id', async (c) => {
|
|
|
155
157
|
return c.json({ success: true });
|
|
156
158
|
}
|
|
157
159
|
catch (error) {
|
|
158
|
-
|
|
160
|
+
log.error('Delete error', error instanceof Error ? error : new Error(String(error)));
|
|
159
161
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to delete label' }, 500);
|
|
160
162
|
}
|
|
161
163
|
});
|
|
@@ -174,7 +176,7 @@ labelsRoutes.get('/tickets/:ticketId/labels', async (c) => {
|
|
|
174
176
|
});
|
|
175
177
|
}
|
|
176
178
|
catch (error) {
|
|
177
|
-
|
|
179
|
+
log.error('Get ticket labels error', error instanceof Error ? error : new Error(String(error)));
|
|
178
180
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to get ticket labels' }, 500);
|
|
179
181
|
}
|
|
180
182
|
});
|
|
@@ -201,7 +203,7 @@ labelsRoutes.put('/tickets/:ticketId/labels', async (c) => {
|
|
|
201
203
|
});
|
|
202
204
|
}
|
|
203
205
|
catch (error) {
|
|
204
|
-
|
|
206
|
+
log.error('Set ticket labels error', error instanceof Error ? error : new Error(String(error)));
|
|
205
207
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to set ticket labels' }, 500);
|
|
206
208
|
}
|
|
207
209
|
});
|
|
@@ -217,7 +219,7 @@ labelsRoutes.post('/tickets/:ticketId/labels/:labelId', async (c) => {
|
|
|
217
219
|
return c.json({ success: true });
|
|
218
220
|
}
|
|
219
221
|
catch (error) {
|
|
220
|
-
|
|
222
|
+
log.error('Add label to ticket error', error instanceof Error ? error : new Error(String(error)));
|
|
221
223
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to add label' }, 500);
|
|
222
224
|
}
|
|
223
225
|
});
|
|
@@ -233,7 +235,7 @@ labelsRoutes.delete('/tickets/:ticketId/labels/:labelId', async (c) => {
|
|
|
233
235
|
return c.json({ success: true });
|
|
234
236
|
}
|
|
235
237
|
catch (error) {
|
|
236
|
-
|
|
238
|
+
log.error('Remove label from ticket error', error instanceof Error ? error : new Error(String(error)));
|
|
237
239
|
return c.json({ error: error instanceof Error ? error.message : 'Failed to remove label' }, 500);
|
|
238
240
|
}
|
|
239
241
|
});
|
package/dist/routes/oobe.js
CHANGED
|
@@ -15,7 +15,9 @@ import { createSession } from '../auth/auth-service.js';
|
|
|
15
15
|
import { setCookie } from 'hono/cookie';
|
|
16
16
|
import { hashPassword, validatePasswordStrength } from '../auth/password.js';
|
|
17
17
|
import { invalidateLocalAdminCache } from '../auth/middleware.js';
|
|
18
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
18
19
|
const oobe = new Hono();
|
|
20
|
+
const log = createContextualLogger('OOBE');
|
|
19
21
|
const COOKIE_OPTIONS = {
|
|
20
22
|
httpOnly: true,
|
|
21
23
|
secure: process.env.NODE_ENV === 'production',
|
|
@@ -90,7 +92,7 @@ oobe.get('/status', async (c) => {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
catch (error) {
|
|
93
|
-
|
|
95
|
+
log.error('Status check error', error instanceof Error ? error : new Error(String(error)));
|
|
94
96
|
return c.json({ needsSetup: true, authMode: 'local' });
|
|
95
97
|
}
|
|
96
98
|
});
|
|
@@ -172,7 +174,7 @@ oobe.post('/setup', async (c) => {
|
|
|
172
174
|
setCookie(c, 'profclaw_session', session.token, COOKIE_OPTIONS);
|
|
173
175
|
// Invalidate cached admin in middleware
|
|
174
176
|
invalidateLocalAdminCache();
|
|
175
|
-
|
|
177
|
+
log.info(`Local admin created: ${name}`);
|
|
176
178
|
return c.json({
|
|
177
179
|
success: true,
|
|
178
180
|
user: {
|
|
@@ -184,7 +186,7 @@ oobe.post('/setup', async (c) => {
|
|
|
184
186
|
});
|
|
185
187
|
}
|
|
186
188
|
catch (error) {
|
|
187
|
-
|
|
189
|
+
log.error('Setup error', error instanceof Error ? error : new Error(String(error)));
|
|
188
190
|
return c.json({
|
|
189
191
|
error: 'Setup failed',
|
|
190
192
|
details: error instanceof Error ? error.message : 'Unknown',
|
|
@@ -325,7 +327,7 @@ oobe.post('/validate-ai', async (c) => {
|
|
|
325
327
|
return c.json({ valid: false, error: 'API key is required' }, 400);
|
|
326
328
|
}
|
|
327
329
|
catch (error) {
|
|
328
|
-
|
|
330
|
+
log.error('AI validation error', error instanceof Error ? error : new Error(String(error)));
|
|
329
331
|
return c.json({ valid: false, error: 'Validation failed' }, 500);
|
|
330
332
|
}
|
|
331
333
|
});
|
|
@@ -390,14 +392,14 @@ oobe.post('/enable-multiuser', async (c) => {
|
|
|
390
392
|
});
|
|
391
393
|
// Invalidate cached admin
|
|
392
394
|
invalidateLocalAdminCache();
|
|
393
|
-
|
|
395
|
+
log.info(`Multi-user mode enabled for: ${email}`);
|
|
394
396
|
return c.json({
|
|
395
397
|
success: true,
|
|
396
398
|
message: 'Multi-user authentication enabled',
|
|
397
399
|
});
|
|
398
400
|
}
|
|
399
401
|
catch (error) {
|
|
400
|
-
|
|
402
|
+
log.error('Enable multi-user error', error instanceof Error ? error : new Error(String(error)));
|
|
401
403
|
return c.json({ error: 'Failed to enable multi-user mode' }, 500);
|
|
402
404
|
}
|
|
403
405
|
});
|
package/dist/routes/openapi.js
CHANGED
|
@@ -12,7 +12,7 @@ const spec = {
|
|
|
12
12
|
title: 'profClaw API',
|
|
13
13
|
version: '0.1.0',
|
|
14
14
|
description: 'AI-powered task orchestration, ticket management, and chat system. Supports multi-provider AI (Anthropic, OpenAI, Google, Ollama) with agentic tool execution.',
|
|
15
|
-
contact: { name: 'profClaw', url: 'https://profclaw.
|
|
15
|
+
contact: { name: 'profClaw', url: 'https://profclaw.ai' },
|
|
16
16
|
license: { name: 'MIT' },
|
|
17
17
|
},
|
|
18
18
|
servers: [
|
package/dist/routes/projects.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Multi-project support with custom ticket prefixes and sprint management.
|
|
5
5
|
*/
|
|
6
6
|
import { Hono } from 'hono';
|
|
7
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
8
|
+
const log = createContextualLogger('Projects');
|
|
7
9
|
import {
|
|
8
10
|
// Projects
|
|
9
11
|
createProject, getProject, getProjectByKey, getProjectWithRelations, updateProject, archiveProject, deleteProject, queryProjects, createProjectExternalLink, getProjectExternalLinks, findProjectByExternalId, getOrCreateDefaultProject, migrateTicketsToDefaultProject,
|
|
@@ -67,7 +69,7 @@ projectsRouter.get('/', async (c) => {
|
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
catch (error) {
|
|
70
|
-
|
|
72
|
+
log.error('Error querying projects', error instanceof Error ? error : new Error(String(error)));
|
|
71
73
|
return c.json({ error: 'Failed to query projects' }, 500);
|
|
72
74
|
}
|
|
73
75
|
});
|
|
@@ -91,7 +93,7 @@ projectsRouter.post('/', async (c) => {
|
|
|
91
93
|
}, 201);
|
|
92
94
|
}
|
|
93
95
|
catch (error) {
|
|
94
|
-
|
|
96
|
+
log.error('Error creating project', error instanceof Error ? error : new Error(String(error)));
|
|
95
97
|
// Check for unique constraint violation
|
|
96
98
|
if (errorMessageIncludes(error, 'UNIQUE constraint failed') || getErrorCode(error) === 'SQLITE_CONSTRAINT') {
|
|
97
99
|
return c.json({
|
|
@@ -114,7 +116,7 @@ projectsRouter.get('/default', async (c) => {
|
|
|
114
116
|
return c.json({ project });
|
|
115
117
|
}
|
|
116
118
|
catch (error) {
|
|
117
|
-
|
|
119
|
+
log.error('Error getting default project', error instanceof Error ? error : new Error(String(error)));
|
|
118
120
|
return c.json({ error: 'Failed to get default project' }, 500);
|
|
119
121
|
}
|
|
120
122
|
});
|
|
@@ -130,7 +132,7 @@ projectsRouter.post('/migrate', async (c) => {
|
|
|
130
132
|
});
|
|
131
133
|
}
|
|
132
134
|
catch (error) {
|
|
133
|
-
|
|
135
|
+
log.error('Error migrating tickets', error instanceof Error ? error : new Error(String(error)));
|
|
134
136
|
return c.json({ error: 'Failed to migrate tickets' }, 500);
|
|
135
137
|
}
|
|
136
138
|
});
|
|
@@ -147,7 +149,7 @@ projectsRouter.get('/by-key/:key', async (c) => {
|
|
|
147
149
|
return c.json({ project });
|
|
148
150
|
}
|
|
149
151
|
catch (error) {
|
|
150
|
-
|
|
152
|
+
log.error('Error getting project by key', error instanceof Error ? error : new Error(String(error)));
|
|
151
153
|
return c.json({ error: 'Failed to get project' }, 500);
|
|
152
154
|
}
|
|
153
155
|
});
|
|
@@ -165,7 +167,7 @@ projectsRouter.get('/by-external/:platform/:externalId', async (c) => {
|
|
|
165
167
|
return c.json({ project });
|
|
166
168
|
}
|
|
167
169
|
catch (error) {
|
|
168
|
-
|
|
170
|
+
log.error('Error finding project by external ID', error instanceof Error ? error : new Error(String(error)));
|
|
169
171
|
return c.json({ error: 'Failed to find project' }, 500);
|
|
170
172
|
}
|
|
171
173
|
});
|
|
@@ -185,7 +187,7 @@ projectsRouter.get('/:id', async (c) => {
|
|
|
185
187
|
return c.json({ project });
|
|
186
188
|
}
|
|
187
189
|
catch (error) {
|
|
188
|
-
|
|
190
|
+
log.error('Error getting project', error instanceof Error ? error : new Error(String(error)));
|
|
189
191
|
return c.json({ error: 'Failed to get project' }, 500);
|
|
190
192
|
}
|
|
191
193
|
});
|
|
@@ -210,7 +212,7 @@ projectsRouter.patch('/:id', async (c) => {
|
|
|
210
212
|
});
|
|
211
213
|
}
|
|
212
214
|
catch (error) {
|
|
213
|
-
|
|
215
|
+
log.error('Error updating project', error instanceof Error ? error : new Error(String(error)));
|
|
214
216
|
if (errorMessageIncludes(error, 'not found')) {
|
|
215
217
|
return c.json({ error: 'Project not found' }, 404);
|
|
216
218
|
}
|
|
@@ -233,7 +235,7 @@ projectsRouter.post('/:id/archive', async (c) => {
|
|
|
233
235
|
});
|
|
234
236
|
}
|
|
235
237
|
catch (error) {
|
|
236
|
-
|
|
238
|
+
log.error('Error archiving project', error instanceof Error ? error : new Error(String(error)));
|
|
237
239
|
if (errorMessageIncludes(error, 'not found')) {
|
|
238
240
|
return c.json({ error: 'Project not found' }, 404);
|
|
239
241
|
}
|
|
@@ -250,7 +252,7 @@ projectsRouter.delete('/:id', async (c) => {
|
|
|
250
252
|
return c.json({ message: 'Project deleted' });
|
|
251
253
|
}
|
|
252
254
|
catch (error) {
|
|
253
|
-
|
|
255
|
+
log.error('Error deleting project', error instanceof Error ? error : new Error(String(error)));
|
|
254
256
|
return c.json({ error: 'Failed to delete project' }, 500);
|
|
255
257
|
}
|
|
256
258
|
});
|
|
@@ -265,7 +267,7 @@ projectsRouter.get('/:id/external-links', async (c) => {
|
|
|
265
267
|
return c.json({ externalLinks: links });
|
|
266
268
|
}
|
|
267
269
|
catch (error) {
|
|
268
|
-
|
|
270
|
+
log.error('Error getting external links', error instanceof Error ? error : new Error(String(error)));
|
|
269
271
|
return c.json({ error: 'Failed to get external links' }, 500);
|
|
270
272
|
}
|
|
271
273
|
});
|
|
@@ -290,7 +292,7 @@ projectsRouter.post('/:id/external-links', async (c) => {
|
|
|
290
292
|
}, 201);
|
|
291
293
|
}
|
|
292
294
|
catch (error) {
|
|
293
|
-
|
|
295
|
+
log.error('Error creating external link', error instanceof Error ? error : new Error(String(error)));
|
|
294
296
|
return c.json({ error: 'Failed to create external link' }, 500);
|
|
295
297
|
}
|
|
296
298
|
});
|
|
@@ -329,7 +331,7 @@ projectsRouter.get('/:projectId/sprints', async (c) => {
|
|
|
329
331
|
});
|
|
330
332
|
}
|
|
331
333
|
catch (error) {
|
|
332
|
-
|
|
334
|
+
log.error('Error querying sprints', error instanceof Error ? error : new Error(String(error)));
|
|
333
335
|
return c.json({ error: 'Failed to query sprints' }, 500);
|
|
334
336
|
}
|
|
335
337
|
});
|
|
@@ -354,7 +356,7 @@ projectsRouter.post('/:projectId/sprints', async (c) => {
|
|
|
354
356
|
}, 201);
|
|
355
357
|
}
|
|
356
358
|
catch (error) {
|
|
357
|
-
|
|
359
|
+
log.error('Error creating sprint', error instanceof Error ? error : new Error(String(error)));
|
|
358
360
|
if (errorMessageIncludes(error, 'not found')) {
|
|
359
361
|
return c.json({ error: 'Project not found' }, 404);
|
|
360
362
|
}
|
|
@@ -377,7 +379,7 @@ projectsRouter.get('/:projectId/sprints/active', async (c) => {
|
|
|
377
379
|
return c.json({ sprint });
|
|
378
380
|
}
|
|
379
381
|
catch (error) {
|
|
380
|
-
|
|
382
|
+
log.error('Error getting active sprint', error instanceof Error ? error : new Error(String(error)));
|
|
381
383
|
return c.json({ error: 'Failed to get active sprint' }, 500);
|
|
382
384
|
}
|
|
383
385
|
});
|
|
@@ -397,7 +399,7 @@ projectsRouter.get('/:projectId/sprints/:sprintId', async (c) => {
|
|
|
397
399
|
return c.json({ sprint });
|
|
398
400
|
}
|
|
399
401
|
catch (error) {
|
|
400
|
-
|
|
402
|
+
log.error('Error getting sprint', error instanceof Error ? error : new Error(String(error)));
|
|
401
403
|
return c.json({ error: 'Failed to get sprint' }, 500);
|
|
402
404
|
}
|
|
403
405
|
});
|
|
@@ -422,7 +424,7 @@ projectsRouter.patch('/:projectId/sprints/:sprintId', async (c) => {
|
|
|
422
424
|
});
|
|
423
425
|
}
|
|
424
426
|
catch (error) {
|
|
425
|
-
|
|
427
|
+
log.error('Error updating sprint', error instanceof Error ? error : new Error(String(error)));
|
|
426
428
|
if (errorMessageIncludes(error, 'not found')) {
|
|
427
429
|
return c.json({ error: 'Sprint not found' }, 404);
|
|
428
430
|
}
|
|
@@ -445,7 +447,7 @@ projectsRouter.post('/:projectId/sprints/:sprintId/start', async (c) => {
|
|
|
445
447
|
});
|
|
446
448
|
}
|
|
447
449
|
catch (error) {
|
|
448
|
-
|
|
450
|
+
log.error('Error starting sprint', error instanceof Error ? error : new Error(String(error)));
|
|
449
451
|
if (errorMessageIncludes(error, 'not found')) {
|
|
450
452
|
return c.json({ error: 'Sprint not found' }, 404);
|
|
451
453
|
}
|
|
@@ -468,7 +470,7 @@ projectsRouter.post('/:projectId/sprints/:sprintId/complete', async (c) => {
|
|
|
468
470
|
});
|
|
469
471
|
}
|
|
470
472
|
catch (error) {
|
|
471
|
-
|
|
473
|
+
log.error('Error completing sprint', error instanceof Error ? error : new Error(String(error)));
|
|
472
474
|
if (errorMessageIncludes(error, 'not found')) {
|
|
473
475
|
return c.json({ error: 'Sprint not found' }, 404);
|
|
474
476
|
}
|
|
@@ -491,7 +493,7 @@ projectsRouter.post('/:projectId/sprints/:sprintId/cancel', async (c) => {
|
|
|
491
493
|
});
|
|
492
494
|
}
|
|
493
495
|
catch (error) {
|
|
494
|
-
|
|
496
|
+
log.error('Error cancelling sprint', error instanceof Error ? error : new Error(String(error)));
|
|
495
497
|
if (errorMessageIncludes(error, 'not found')) {
|
|
496
498
|
return c.json({ error: 'Sprint not found' }, 404);
|
|
497
499
|
}
|
|
@@ -508,7 +510,7 @@ projectsRouter.delete('/:projectId/sprints/:sprintId', async (c) => {
|
|
|
508
510
|
return c.json({ message: 'Sprint deleted' });
|
|
509
511
|
}
|
|
510
512
|
catch (error) {
|
|
511
|
-
|
|
513
|
+
log.error('Error deleting sprint', error instanceof Error ? error : new Error(String(error)));
|
|
512
514
|
return c.json({ error: 'Failed to delete sprint' }, 500);
|
|
513
515
|
}
|
|
514
516
|
});
|
|
@@ -523,7 +525,7 @@ projectsRouter.get('/:projectId/sprints/:sprintId/tickets', async (c) => {
|
|
|
523
525
|
return c.json({ ticketIds });
|
|
524
526
|
}
|
|
525
527
|
catch (error) {
|
|
526
|
-
|
|
528
|
+
log.error('Error getting sprint tickets', error instanceof Error ? error : new Error(String(error)));
|
|
527
529
|
return c.json({ error: 'Failed to get sprint tickets' }, 500);
|
|
528
530
|
}
|
|
529
531
|
});
|
|
@@ -548,7 +550,7 @@ projectsRouter.post('/:projectId/sprints/:sprintId/tickets', async (c) => {
|
|
|
548
550
|
}, 201);
|
|
549
551
|
}
|
|
550
552
|
catch (error) {
|
|
551
|
-
|
|
553
|
+
log.error('Error adding tickets to sprint', error instanceof Error ? error : new Error(String(error)));
|
|
552
554
|
if (errorMessageIncludes(error, 'not found')) {
|
|
553
555
|
return c.json({ error: 'Sprint not found' }, 404);
|
|
554
556
|
}
|
|
@@ -566,7 +568,7 @@ projectsRouter.delete('/:projectId/sprints/:sprintId/tickets/:ticketId', async (
|
|
|
566
568
|
return c.json({ message: 'Ticket removed from sprint' });
|
|
567
569
|
}
|
|
568
570
|
catch (error) {
|
|
569
|
-
|
|
571
|
+
log.error('Error removing ticket from sprint', error instanceof Error ? error : new Error(String(error)));
|
|
570
572
|
return c.json({ error: 'Failed to remove ticket from sprint' }, 500);
|
|
571
573
|
}
|
|
572
574
|
});
|
|
@@ -584,7 +586,7 @@ projectsRouter.put('/:projectId/sprints/:sprintId/tickets/reorder', async (c) =>
|
|
|
584
586
|
return c.json({ message: 'Tickets reordered' });
|
|
585
587
|
}
|
|
586
588
|
catch (error) {
|
|
587
|
-
|
|
589
|
+
log.error('Error reordering sprint tickets', error instanceof Error ? error : new Error(String(error)));
|
|
588
590
|
return c.json({ error: 'Failed to reorder tickets' }, 500);
|
|
589
591
|
}
|
|
590
592
|
});
|
package/dist/routes/settings.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
3
|
+
const log = createContextualLogger('Settings');
|
|
2
4
|
import { getSettings, updateSettings, resetSettings, UpdateSettingsSchema, getPluginHealth, togglePlugin, } from '../settings/index.js';
|
|
3
5
|
const settings = new Hono();
|
|
4
6
|
async function parseJsonBody(c) {
|
|
@@ -26,7 +28,7 @@ settings.get('/', async (c) => {
|
|
|
26
28
|
return c.json({ settings: currentSettings });
|
|
27
29
|
}
|
|
28
30
|
catch (error) {
|
|
29
|
-
|
|
31
|
+
log.error('Error fetching settings', error instanceof Error ? error : new Error(String(error)));
|
|
30
32
|
return c.json({
|
|
31
33
|
error: 'Failed to fetch settings',
|
|
32
34
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -54,7 +56,7 @@ settings.patch('/', async (c) => {
|
|
|
54
56
|
});
|
|
55
57
|
}
|
|
56
58
|
catch (error) {
|
|
57
|
-
|
|
59
|
+
log.error('Error updating settings', error instanceof Error ? error : new Error(String(error)));
|
|
58
60
|
return c.json({
|
|
59
61
|
error: 'Failed to update settings',
|
|
60
62
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -71,7 +73,7 @@ settings.post('/reset', async (c) => {
|
|
|
71
73
|
});
|
|
72
74
|
}
|
|
73
75
|
catch (error) {
|
|
74
|
-
|
|
76
|
+
log.error('Error resetting settings', error instanceof Error ? error : new Error(String(error)));
|
|
75
77
|
return c.json({
|
|
76
78
|
error: 'Failed to reset settings',
|
|
77
79
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -85,7 +87,7 @@ settings.get('/plugins/health', async (c) => {
|
|
|
85
87
|
return c.json({ plugins: health });
|
|
86
88
|
}
|
|
87
89
|
catch (error) {
|
|
88
|
-
|
|
90
|
+
log.error('Error checking plugin health', error instanceof Error ? error : new Error(String(error)));
|
|
89
91
|
return c.json({
|
|
90
92
|
error: 'Failed to check plugin health',
|
|
91
93
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -108,7 +110,7 @@ settings.post('/plugins/:id/toggle', async (c) => {
|
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
112
|
catch (error) {
|
|
111
|
-
|
|
113
|
+
log.error('Error toggling plugin', error instanceof Error ? error : new Error(String(error)));
|
|
112
114
|
return c.json({
|
|
113
115
|
error: 'Failed to toggle plugin',
|
|
114
116
|
message: error instanceof Error ? error.message : 'Unknown error',
|
package/dist/routes/setup.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* first-time setup and configuration checks.
|
|
7
7
|
*/
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
10
|
+
const log = createContextualLogger('Setup');
|
|
9
11
|
import { randomUUID, randomBytes } from 'crypto';
|
|
10
12
|
import { eq } from 'drizzle-orm';
|
|
11
13
|
import { z } from 'zod';
|
|
@@ -103,7 +105,7 @@ setup.get('/status', async (c) => {
|
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
107
|
catch (error) {
|
|
106
|
-
|
|
108
|
+
log.error('Status check error', error instanceof Error ? error : new Error(String(error)));
|
|
107
109
|
return c.json({
|
|
108
110
|
configured: false,
|
|
109
111
|
isFirstTimeSetup: true,
|
|
@@ -202,7 +204,7 @@ setup.post('/github-oauth/validate', async (c) => {
|
|
|
202
204
|
}
|
|
203
205
|
catch (fetchError) {
|
|
204
206
|
// If GitHub API is unreachable, fall back to format validation only
|
|
205
|
-
|
|
207
|
+
log.warn('Could not verify credentials with GitHub API', { error: fetchError instanceof Error ? fetchError.message : String(fetchError) });
|
|
206
208
|
return c.json({
|
|
207
209
|
valid: true,
|
|
208
210
|
message: 'Credentials format is valid. Could not verify with GitHub API.',
|
|
@@ -212,7 +214,7 @@ setup.post('/github-oauth/validate', async (c) => {
|
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
catch (error) {
|
|
215
|
-
|
|
217
|
+
log.error('GitHub OAuth validation error', error instanceof Error ? error : new Error(String(error)));
|
|
216
218
|
return c.json({
|
|
217
219
|
valid: false,
|
|
218
220
|
error: 'Validation failed',
|
|
@@ -252,14 +254,14 @@ setup.post('/github-oauth', async (c) => {
|
|
|
252
254
|
},
|
|
253
255
|
},
|
|
254
256
|
});
|
|
255
|
-
|
|
257
|
+
log.info('GitHub OAuth credentials saved to database');
|
|
256
258
|
return c.json({
|
|
257
259
|
success: true,
|
|
258
260
|
message: 'GitHub OAuth configured successfully.',
|
|
259
261
|
});
|
|
260
262
|
}
|
|
261
263
|
catch (error) {
|
|
262
|
-
|
|
264
|
+
log.error('GitHub OAuth setup error', error instanceof Error ? error : new Error(String(error)));
|
|
263
265
|
return c.json({ error: 'Failed to configure GitHub OAuth' }, 500);
|
|
264
266
|
}
|
|
265
267
|
});
|
|
@@ -328,7 +330,7 @@ setup.post('/admin', adminCreateLimiter, async (c) => {
|
|
|
328
330
|
});
|
|
329
331
|
// Create session
|
|
330
332
|
const session = await createSession(userId);
|
|
331
|
-
|
|
333
|
+
log.info('Admin user created', { email });
|
|
332
334
|
return c.json({
|
|
333
335
|
success: true,
|
|
334
336
|
user: {
|
|
@@ -347,8 +349,7 @@ setup.post('/admin', adminCreateLimiter, async (c) => {
|
|
|
347
349
|
});
|
|
348
350
|
}
|
|
349
351
|
catch (error) {
|
|
350
|
-
|
|
351
|
-
console.error('[Setup] Error stack:', error instanceof Error ? error.stack : 'No stack');
|
|
352
|
+
log.error('Admin creation error', error instanceof Error ? error : new Error(String(error)));
|
|
352
353
|
return c.json({
|
|
353
354
|
error: 'Failed to create admin user',
|
|
354
355
|
details: error instanceof Error ? error.message : String(error)
|
|
@@ -419,7 +420,7 @@ setup.post('/verify-recovery-code', recoveryLimiter, async (c) => {
|
|
|
419
420
|
});
|
|
420
421
|
}
|
|
421
422
|
catch (error) {
|
|
422
|
-
|
|
423
|
+
log.error('Recovery code verification error', error instanceof Error ? error : new Error(String(error)));
|
|
423
424
|
return c.json({ error: 'Failed to verify recovery code' }, 500);
|
|
424
425
|
}
|
|
425
426
|
});
|
|
@@ -472,14 +473,14 @@ setup.post('/reset-password', resetLimiter, async (c) => {
|
|
|
472
473
|
updatedAt: new Date(),
|
|
473
474
|
})
|
|
474
475
|
.where(eq(users.id, user.id));
|
|
475
|
-
|
|
476
|
+
log.info('Password reset for user', { email: user.email });
|
|
476
477
|
return c.json({
|
|
477
478
|
success: true,
|
|
478
479
|
message: 'Password has been reset successfully. You can now sign in.',
|
|
479
480
|
});
|
|
480
481
|
}
|
|
481
482
|
catch (error) {
|
|
482
|
-
|
|
483
|
+
log.error('Password reset error', error instanceof Error ? error : new Error(String(error)));
|
|
483
484
|
return c.json({ error: 'Failed to reset password' }, 500);
|
|
484
485
|
}
|
|
485
486
|
});
|