@lovelybunch/api 1.0.56 → 1.0.57

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.
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const apiKeys: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default apiKeys;
@@ -0,0 +1,120 @@
1
+ import { Hono } from 'hono';
2
+ import { getAuthManager } from '../../../../lib/auth/auth-manager.js';
3
+ import { requireAuth } from '../../../../middleware/auth.js';
4
+ const apiKeys = new Hono();
5
+ /**
6
+ * GET /api/v1/api-keys
7
+ * List all API keys
8
+ */
9
+ apiKeys.get('/', async (c) => {
10
+ try {
11
+ const session = requireAuth(c);
12
+ // If auth is disabled (session is null), return empty list
13
+ if (!session) {
14
+ return c.json({
15
+ success: true,
16
+ data: {
17
+ apiKeys: [],
18
+ },
19
+ });
20
+ }
21
+ const authManager = getAuthManager();
22
+ const keys = await authManager.listApiKeys();
23
+ // Return keys without actual key values
24
+ return c.json({
25
+ success: true,
26
+ data: {
27
+ apiKeys: keys.map((k) => ({
28
+ id: k.id,
29
+ name: k.name,
30
+ keyPreview: k.keyPreview,
31
+ createdBy: k.createdBy,
32
+ createdAt: k.createdAt,
33
+ expiresAt: k.expiresAt,
34
+ lastUsedAt: k.lastUsedAt,
35
+ scopes: k.scopes,
36
+ })),
37
+ },
38
+ });
39
+ }
40
+ catch (error) {
41
+ console.error('List API keys error:', error);
42
+ return c.json({ success: false, error: error.message || 'Failed to list API keys' }, error.message === 'Authentication required' ? 401 : 500);
43
+ }
44
+ });
45
+ /**
46
+ * POST /api/v1/api-keys
47
+ * Create a new API key
48
+ */
49
+ apiKeys.post('/', async (c) => {
50
+ try {
51
+ const session = requireAuth(c);
52
+ if (!session) {
53
+ return c.json({ success: false, error: 'Authentication is required to create API keys' }, 401);
54
+ }
55
+ const authManager = getAuthManager();
56
+ const body = await c.req.json();
57
+ const { name, expiresIn, scopes } = body;
58
+ if (!name) {
59
+ return c.json({ success: false, error: 'Name is required' }, 400);
60
+ }
61
+ if (!scopes || scopes.length === 0) {
62
+ return c.json({ success: false, error: 'At least one scope is required' }, 400);
63
+ }
64
+ // Create API key
65
+ const { apiKey, rawKey } = await authManager.createApiKey(name, session.userId, scopes, expiresIn);
66
+ return c.json({
67
+ success: true,
68
+ data: {
69
+ apiKey: {
70
+ id: apiKey.id,
71
+ name: apiKey.name,
72
+ keyPreview: apiKey.keyPreview,
73
+ createdBy: apiKey.createdBy,
74
+ createdAt: apiKey.createdAt,
75
+ expiresAt: apiKey.expiresAt,
76
+ scopes: apiKey.scopes,
77
+ },
78
+ key: rawKey, // Only returned once!
79
+ },
80
+ message: 'API key created successfully. Save this key securely - it will not be shown again.',
81
+ });
82
+ }
83
+ catch (error) {
84
+ console.error('Create API key error:', error);
85
+ return c.json({ success: false, error: error.message || 'Failed to create API key' }, error.message === 'Authentication required' ? 401 : 500);
86
+ }
87
+ });
88
+ /**
89
+ * DELETE /api/v1/api-keys/:id
90
+ * Delete an API key
91
+ */
92
+ apiKeys.delete('/:id', async (c) => {
93
+ try {
94
+ const session = requireAuth(c);
95
+ if (!session) {
96
+ return c.json({ success: false, error: 'Authentication is required to delete API keys' }, 401);
97
+ }
98
+ const apiKeyId = c.req.param('id');
99
+ const authManager = getAuthManager();
100
+ const keys = await authManager.listApiKeys();
101
+ const key = keys.find((k) => k.id === apiKeyId);
102
+ if (!key) {
103
+ return c.json({ success: false, error: 'API key not found' }, 404);
104
+ }
105
+ // Check if user is admin or the creator of the key
106
+ if (session.role !== 'admin' && key.createdBy !== session.userId) {
107
+ return c.json({ success: false, error: 'Not authorized to delete this API key' }, 403);
108
+ }
109
+ await authManager.deleteApiKey(apiKeyId);
110
+ return c.json({
111
+ success: true,
112
+ message: 'API key deleted successfully',
113
+ });
114
+ }
115
+ catch (error) {
116
+ console.error('Delete API key error:', error);
117
+ return c.json({ success: false, error: error.message || 'Failed to delete API key' }, error.message === 'Authentication required' ? 401 : 500);
118
+ }
119
+ });
120
+ export default apiKeys;
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const auth: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default auth;
@@ -0,0 +1,230 @@
1
+ import { Hono } from 'hono';
2
+ import { setCookie, deleteCookie } from 'hono/cookie';
3
+ import { getAuthManager } from '../../../../lib/auth/auth-manager.js';
4
+ import { getSession } from '../../../../middleware/auth.js';
5
+ const auth = new Hono();
6
+ /**
7
+ * POST /api/v1/auth/login
8
+ * Login with email and password
9
+ */
10
+ auth.post('/login', async (c) => {
11
+ try {
12
+ const authManager = getAuthManager();
13
+ const body = await c.req.json();
14
+ const { email, password } = body;
15
+ if (!email || !password) {
16
+ return c.json({ success: false, error: 'Email and password are required' }, 400);
17
+ }
18
+ // Verify credentials
19
+ const user = await authManager.verifyCredentials(email, password);
20
+ if (!user) {
21
+ return c.json({ success: false, error: 'Invalid email or password' }, 401);
22
+ }
23
+ // Generate token
24
+ const token = await authManager.generateToken(user);
25
+ // Get session config
26
+ const config = await authManager.loadAuthConfig();
27
+ // Set cookie
28
+ setCookie(c, config.session.cookieName, token, {
29
+ httpOnly: true,
30
+ secure: config.session.secure || false,
31
+ sameSite: 'Lax',
32
+ maxAge: authManager['parseExpiry'](config.session.expiresIn),
33
+ path: '/',
34
+ });
35
+ return c.json({
36
+ success: true,
37
+ data: {
38
+ user: {
39
+ id: user.id,
40
+ email: user.email,
41
+ name: user.name,
42
+ role: user.role,
43
+ },
44
+ token, // Also return token for programmatic use
45
+ },
46
+ });
47
+ }
48
+ catch (error) {
49
+ console.error('Login error:', error);
50
+ return c.json({ success: false, error: 'Login failed' }, 500);
51
+ }
52
+ });
53
+ /**
54
+ * POST /api/v1/auth/register
55
+ * Register a new user (must be whitelisted)
56
+ */
57
+ auth.post('/register', async (c) => {
58
+ try {
59
+ const authManager = getAuthManager();
60
+ const body = await c.req.json();
61
+ const { email, password, name } = body;
62
+ if (!email || !password || !name) {
63
+ return c.json({ success: false, error: 'Email, password, and name are required' }, 400);
64
+ }
65
+ // Validate password strength
66
+ if (password.length < 8) {
67
+ return c.json({ success: false, error: 'Password must be at least 8 characters' }, 400);
68
+ }
69
+ // Check if email is whitelisted
70
+ const isWhitelisted = await authManager.isEmailWhitelisted(email);
71
+ if (!isWhitelisted) {
72
+ return c.json({ success: false, error: 'Email not authorized for registration' }, 403);
73
+ }
74
+ // Register user
75
+ const user = await authManager.registerUser(email, password, name);
76
+ // Generate token
77
+ const token = await authManager.generateToken(user);
78
+ // Get session config
79
+ const config = await authManager.loadAuthConfig();
80
+ // Set cookie
81
+ setCookie(c, config.session.cookieName, token, {
82
+ httpOnly: true,
83
+ secure: config.session.secure || false,
84
+ sameSite: 'Lax',
85
+ maxAge: authManager['parseExpiry'](config.session.expiresIn),
86
+ path: '/',
87
+ });
88
+ return c.json({
89
+ success: true,
90
+ data: {
91
+ user: {
92
+ id: user.id,
93
+ email: user.email,
94
+ name: user.name,
95
+ role: user.role,
96
+ },
97
+ token,
98
+ },
99
+ });
100
+ }
101
+ catch (error) {
102
+ console.error('Registration error:', error);
103
+ return c.json({ success: false, error: error.message || 'Registration failed' }, 400);
104
+ }
105
+ });
106
+ /**
107
+ * POST /api/v1/auth/logout
108
+ * Logout and clear session
109
+ */
110
+ auth.post('/logout', async (c) => {
111
+ try {
112
+ const authManager = getAuthManager();
113
+ const config = await authManager.loadAuthConfig();
114
+ // Clear cookie
115
+ deleteCookie(c, config.session.cookieName, {
116
+ path: '/',
117
+ });
118
+ return c.json({
119
+ success: true,
120
+ message: 'Logged out successfully',
121
+ });
122
+ }
123
+ catch (error) {
124
+ console.error('Logout error:', error);
125
+ return c.json({ success: false, error: 'Logout failed' }, 500);
126
+ }
127
+ });
128
+ /**
129
+ * GET /api/v1/auth/me
130
+ * Get current user info
131
+ */
132
+ auth.get('/me', async (c) => {
133
+ try {
134
+ const session = getSession(c);
135
+ if (!session) {
136
+ return c.json({ success: false, error: 'Not authenticated' }, 401);
137
+ }
138
+ const authManager = getAuthManager();
139
+ const user = await authManager.findUserById(session.userId);
140
+ if (!user) {
141
+ return c.json({ success: false, error: 'User not found' }, 404);
142
+ }
143
+ return c.json({
144
+ success: true,
145
+ data: {
146
+ user: {
147
+ id: user.id,
148
+ email: user.email,
149
+ name: user.name,
150
+ role: user.role,
151
+ lastLoginAt: user.lastLoginAt,
152
+ },
153
+ },
154
+ });
155
+ }
156
+ catch (error) {
157
+ console.error('Get user error:', error);
158
+ return c.json({ success: false, error: 'Failed to get user info' }, 500);
159
+ }
160
+ });
161
+ /**
162
+ * POST /api/v1/auth/change-password
163
+ * Change current user's password
164
+ */
165
+ auth.post('/change-password', async (c) => {
166
+ try {
167
+ const session = getSession(c);
168
+ if (!session) {
169
+ return c.json({ success: false, error: 'Not authenticated' }, 401);
170
+ }
171
+ const authManager = getAuthManager();
172
+ const body = await c.req.json();
173
+ const { currentPassword, newPassword } = body;
174
+ if (!currentPassword || !newPassword) {
175
+ return c.json({ success: false, error: 'Current and new password are required' }, 400);
176
+ }
177
+ // Validate new password strength
178
+ if (newPassword.length < 8) {
179
+ return c.json({ success: false, error: 'New password must be at least 8 characters' }, 400);
180
+ }
181
+ await authManager.changePassword(session.userId, currentPassword, newPassword);
182
+ return c.json({
183
+ success: true,
184
+ message: 'Password changed successfully',
185
+ });
186
+ }
187
+ catch (error) {
188
+ console.error('Change password error:', error);
189
+ return c.json({ success: false, error: error.message || 'Failed to change password' }, 400);
190
+ }
191
+ });
192
+ /**
193
+ * GET /api/v1/auth/status
194
+ * Check if auth is enabled
195
+ */
196
+ auth.get('/status', async (c) => {
197
+ try {
198
+ const authManager = getAuthManager();
199
+ const authEnabled = await authManager.isAuthEnabled();
200
+ let config = null;
201
+ if (authEnabled) {
202
+ const authConfig = await authManager.loadAuthConfig();
203
+ config = {
204
+ allowRegistration: authConfig.allowRegistration,
205
+ providers: {
206
+ local: authConfig.providers.local.enabled,
207
+ google: authConfig.providers.oauth.google?.enabled || false,
208
+ github: authConfig.providers.oauth.github?.enabled || false,
209
+ },
210
+ };
211
+ }
212
+ return c.json({
213
+ success: true,
214
+ data: {
215
+ enabled: authEnabled,
216
+ config,
217
+ },
218
+ });
219
+ }
220
+ catch (error) {
221
+ console.error('Auth status error:', error);
222
+ return c.json({
223
+ success: true,
224
+ data: {
225
+ enabled: false,
226
+ },
227
+ });
228
+ }
229
+ });
230
+ export default auth;
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const authSettings: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default authSettings;
@@ -0,0 +1,249 @@
1
+ import { Hono } from 'hono';
2
+ import { getAuthManager } from '../../../../lib/auth/auth-manager.js';
3
+ import { requireAdmin } from '../../../../middleware/auth.js';
4
+ const authSettings = new Hono();
5
+ /**
6
+ * GET /api/v1/auth-settings
7
+ * Get auth configuration (admin only)
8
+ */
9
+ authSettings.get('/', async (c) => {
10
+ try {
11
+ requireAdmin(c);
12
+ const authManager = getAuthManager();
13
+ const config = await authManager.loadAuthConfig();
14
+ // Return config without sensitive data (passwords, secrets, API keys)
15
+ return c.json({
16
+ success: true,
17
+ data: {
18
+ enabled: config.enabled,
19
+ allowRegistration: config.allowRegistration,
20
+ providers: {
21
+ local: {
22
+ enabled: config.providers.local.enabled,
23
+ users: config.providers.local.users.map((u) => ({
24
+ id: u.id,
25
+ email: u.email,
26
+ name: u.name,
27
+ role: u.role,
28
+ registered: u.registered,
29
+ createdAt: u.createdAt,
30
+ updatedAt: u.updatedAt,
31
+ lastLoginAt: u.lastLoginAt,
32
+ })),
33
+ },
34
+ oauth: {
35
+ google: config.providers.oauth.google
36
+ ? {
37
+ enabled: config.providers.oauth.google.enabled,
38
+ clientId: config.providers.oauth.google.clientId
39
+ ? '***'
40
+ : undefined,
41
+ hasClientSecret: !!config.providers.oauth.google.clientSecret,
42
+ callbackUrl: config.providers.oauth.google.callbackUrl,
43
+ }
44
+ : undefined,
45
+ github: config.providers.oauth.github
46
+ ? {
47
+ enabled: config.providers.oauth.github.enabled,
48
+ clientId: config.providers.oauth.github.clientId
49
+ ? '***'
50
+ : undefined,
51
+ hasClientSecret: !!config.providers.oauth.github.clientSecret,
52
+ callbackUrl: config.providers.oauth.github.callbackUrl,
53
+ }
54
+ : undefined,
55
+ },
56
+ },
57
+ session: {
58
+ expiresIn: config.session.expiresIn,
59
+ cookieName: config.session.cookieName,
60
+ secure: config.session.secure,
61
+ },
62
+ },
63
+ });
64
+ }
65
+ catch (error) {
66
+ console.error('Get auth settings error:', error);
67
+ return c.json({ success: false, error: error.message || 'Failed to get auth settings' }, error.message === 'Admin access required' ? 403 : 500);
68
+ }
69
+ });
70
+ /**
71
+ * PUT /api/v1/auth-settings
72
+ * Update auth configuration (admin only)
73
+ */
74
+ authSettings.put('/', async (c) => {
75
+ try {
76
+ requireAdmin(c);
77
+ const authManager = getAuthManager();
78
+ const config = await authManager.loadAuthConfig();
79
+ const body = await c.req.json();
80
+ // Update allowed fields
81
+ if (typeof body.enabled === 'boolean') {
82
+ config.enabled = body.enabled;
83
+ }
84
+ if (typeof body.allowRegistration === 'boolean') {
85
+ config.allowRegistration = body.allowRegistration;
86
+ }
87
+ if (body.session) {
88
+ if (body.session.expiresIn) {
89
+ config.session.expiresIn = body.session.expiresIn;
90
+ }
91
+ if (typeof body.session.secure === 'boolean') {
92
+ config.session.secure = body.session.secure;
93
+ }
94
+ }
95
+ await authManager.saveAuthConfig(config);
96
+ return c.json({
97
+ success: true,
98
+ message: 'Auth settings updated successfully',
99
+ });
100
+ }
101
+ catch (error) {
102
+ console.error('Update auth settings error:', error);
103
+ return c.json({ success: false, error: error.message || 'Failed to update auth settings' }, error.message === 'Admin access required' ? 403 : 500);
104
+ }
105
+ });
106
+ /**
107
+ * POST /api/v1/auth-settings/users
108
+ * Add a new whitelisted user (admin only)
109
+ */
110
+ authSettings.post('/users', async (c) => {
111
+ try {
112
+ requireAdmin(c);
113
+ const authManager = getAuthManager();
114
+ const body = await c.req.json();
115
+ const { email, name, role = 'viewer' } = body;
116
+ if (!email || !name) {
117
+ return c.json({ success: false, error: 'Email and name are required' }, 400);
118
+ }
119
+ const user = await authManager.addWhitelistedUser(email, name, role);
120
+ return c.json({
121
+ success: true,
122
+ data: {
123
+ user: {
124
+ id: user.id,
125
+ email: user.email,
126
+ name: user.name,
127
+ role: user.role,
128
+ registered: user.registered,
129
+ },
130
+ },
131
+ });
132
+ }
133
+ catch (error) {
134
+ console.error('Add user error:', error);
135
+ return c.json({ success: false, error: error.message || 'Failed to add user' }, error.message === 'Admin access required' ? 403 : 400);
136
+ }
137
+ });
138
+ /**
139
+ * PUT /api/v1/auth-settings/users/:id
140
+ * Update a user (admin only)
141
+ */
142
+ authSettings.put('/users/:id', async (c) => {
143
+ try {
144
+ requireAdmin(c);
145
+ const authManager = getAuthManager();
146
+ const userId = c.req.param('id');
147
+ const body = await c.req.json();
148
+ const user = await authManager.findUserById(userId);
149
+ if (!user) {
150
+ return c.json({ success: false, error: 'User not found' }, 404);
151
+ }
152
+ // Update role if provided
153
+ if (body.role) {
154
+ await authManager.updateUserRole(userId, body.role);
155
+ }
156
+ // Update name if provided
157
+ if (body.name) {
158
+ const config = await authManager.loadAuthConfig();
159
+ const userIndex = config.providers.local.users.findIndex((u) => u.id === userId);
160
+ if (userIndex !== -1) {
161
+ config.providers.local.users[userIndex].name = body.name;
162
+ config.providers.local.users[userIndex].updatedAt = new Date();
163
+ await authManager.saveAuthConfig(config);
164
+ }
165
+ }
166
+ return c.json({
167
+ success: true,
168
+ message: 'User updated successfully',
169
+ });
170
+ }
171
+ catch (error) {
172
+ console.error('Update user error:', error);
173
+ return c.json({ success: false, error: error.message || 'Failed to update user' }, error.message === 'Admin access required' ? 403 : 500);
174
+ }
175
+ });
176
+ /**
177
+ * POST /api/v1/auth-settings/users/:id/reset-password
178
+ * Admin reset user password (admin only)
179
+ */
180
+ authSettings.post('/users/:id/reset-password', async (c) => {
181
+ try {
182
+ requireAdmin(c);
183
+ const authManager = getAuthManager();
184
+ const userId = c.req.param('id');
185
+ const body = await c.req.json();
186
+ if (!body.newPassword) {
187
+ return c.json({ success: false, error: 'New password is required' }, 400);
188
+ }
189
+ if (body.newPassword.length < 8) {
190
+ return c.json({ success: false, error: 'Password must be at least 8 characters' }, 400);
191
+ }
192
+ await authManager.adminResetPassword(userId, body.newPassword);
193
+ return c.json({
194
+ success: true,
195
+ message: 'Password reset successfully',
196
+ });
197
+ }
198
+ catch (error) {
199
+ console.error('Reset password error:', error);
200
+ return c.json({ success: false, error: error.message || 'Failed to reset password' }, error.message === 'Admin access required' ? 403 : 400);
201
+ }
202
+ });
203
+ /**
204
+ * DELETE /api/v1/auth-settings/users/:id
205
+ * Remove a user (admin only)
206
+ */
207
+ authSettings.delete('/users/:id', async (c) => {
208
+ try {
209
+ requireAdmin(c);
210
+ const authManager = getAuthManager();
211
+ const userId = c.req.param('id');
212
+ await authManager.removeUser(userId);
213
+ return c.json({
214
+ success: true,
215
+ message: 'User removed successfully',
216
+ });
217
+ }
218
+ catch (error) {
219
+ console.error('Remove user error:', error);
220
+ return c.json({ success: false, error: error.message || 'Failed to remove user' }, error.message === 'Admin access required' ? 403 : 400);
221
+ }
222
+ });
223
+ /**
224
+ * PUT /api/v1/auth-settings/oauth/:provider
225
+ * Configure OAuth provider (admin only)
226
+ */
227
+ authSettings.put('/oauth/:provider', async (c) => {
228
+ try {
229
+ requireAdmin(c);
230
+ const authManager = getAuthManager();
231
+ const provider = c.req.param('provider');
232
+ const body = await c.req.json();
233
+ const config = await authManager.loadAuthConfig();
234
+ if (!config.providers.oauth) {
235
+ config.providers.oauth = {};
236
+ }
237
+ config.providers.oauth[provider] = body;
238
+ await authManager.saveAuthConfig(config);
239
+ return c.json({
240
+ success: true,
241
+ message: `${provider} OAuth configuration updated successfully`,
242
+ });
243
+ }
244
+ catch (error) {
245
+ console.error('Update OAuth config error:', error);
246
+ return c.json({ success: false, error: error.message || 'Failed to update OAuth configuration' }, error.message === 'Admin access required' ? 403 : 500);
247
+ }
248
+ });
249
+ export default authSettings;
@@ -94,7 +94,7 @@ app.put('/:filename', async (c) => {
94
94
  const updatedMetadata = {
95
95
  ...currentData,
96
96
  ...body.metadata,
97
- updated: new Date().toISOString().split('T')[0],
97
+ updated: new Date().toISOString(),
98
98
  // Ensure these are arrays
99
99
  tags: body.metadata?.tags !== undefined ? body.metadata.tags : (currentData.tags || []),
100
100
  sources: body.metadata?.sources !== undefined ? body.metadata.sources : (currentData.sources || [])
@@ -53,7 +53,7 @@ app.get('/', async (c) => {
53
53
  filename: file,
54
54
  metadata: {
55
55
  ...data,
56
- updated: data.updated || new Date().toISOString().split('T')[0],
56
+ updated: data.updated || new Date().toISOString(),
57
57
  tags: data.tags || [],
58
58
  sources: data.sources || []
59
59
  },
@@ -101,7 +101,7 @@ app.post('/', async (c) => {
101
101
  const now = new Date();
102
102
  const frontmatter = {
103
103
  version: '1.0',
104
- updated: now.toISOString().split('T')[0],
104
+ updated: now.toISOString(),
105
105
  type: 'knowledge',
106
106
  category: body.metadata?.category || 'general',
107
107
  tags: body.metadata?.tags || [],
@@ -21,6 +21,9 @@ app.use('/api/*', cors({
21
21
  }));
22
22
  // Handle trailing slashes consistently for API routes
23
23
  app.use('/api/*', trimTrailingSlash());
24
+ // Import and apply authentication middleware
25
+ import { authMiddleware } from './middleware/auth.js';
26
+ app.use('/api/*', authMiddleware);
24
27
  // Create WebSocket support
25
28
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
26
29
  // WebSocket route for terminal sessions
@@ -75,6 +78,9 @@ app.get('/ws/terminal-preview/:sessionId', upgradeWebSocket((c) => ({
75
78
  },
76
79
  })));
77
80
  // Import and register API routes
81
+ import auth from './routes/api/v1/auth/index.js';
82
+ import authSettings from './routes/api/v1/auth-settings/index.js';
83
+ import apiKeys from './routes/api/v1/api-keys/index.js';
78
84
  import proposals from './routes/api/v1/proposals/index.js';
79
85
  import terminalSessions from './routes/api/v1/terminal/sessions/index.js';
80
86
  import terminalCreate from './routes/api/v1/terminal/[proposalId]/create/index.js';
@@ -95,6 +101,9 @@ import git from './routes/api/v1/git/index.js';
95
101
  import mcp from './routes/api/v1/mcp/index.js';
96
102
  // Register API routes FIRST
97
103
  console.log('🔗 Registering API routes...');
104
+ app.route('/api/v1/auth', auth);
105
+ app.route('/api/v1/auth-settings', authSettings);
106
+ app.route('/api/v1/api-keys', apiKeys);
98
107
  app.route('/api/v1/proposals', proposals);
99
108
  app.route('/api/v1/terminal/sessions', terminalSessions);
100
109
  app.route('/api/v1/terminal/:proposalId/create', terminalCreate);