archicore 0.1.3 → 0.1.5
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.
|
@@ -18,6 +18,15 @@ const state = {
|
|
|
18
18
|
user: null,
|
|
19
19
|
};
|
|
20
20
|
export async function startInteractiveMode() {
|
|
21
|
+
// Prevent process from exiting on unhandled errors
|
|
22
|
+
process.on('uncaughtException', (error) => {
|
|
23
|
+
printError(`Unexpected error: ${error.message}`);
|
|
24
|
+
console.log();
|
|
25
|
+
});
|
|
26
|
+
process.on('unhandledRejection', (reason) => {
|
|
27
|
+
printError(`Unhandled promise rejection: ${reason}`);
|
|
28
|
+
console.log();
|
|
29
|
+
});
|
|
21
30
|
// Check if initialized in current directory
|
|
22
31
|
const initialized = await isInitialized(state.projectPath);
|
|
23
32
|
if (!initialized) {
|
|
@@ -102,14 +111,34 @@ export async function startInteractiveMode() {
|
|
|
102
111
|
});
|
|
103
112
|
rl.on('close', () => {
|
|
104
113
|
if (state.running) {
|
|
105
|
-
// Unexpected close
|
|
114
|
+
// Unexpected close - don't exit, restart readline
|
|
115
|
+
console.log();
|
|
116
|
+
printWarning('Input stream interrupted, restarting...');
|
|
117
|
+
// Recreate readline interface
|
|
118
|
+
const newRl = readline.createInterface({
|
|
119
|
+
input: process.stdin,
|
|
120
|
+
output: process.stdout,
|
|
121
|
+
terminal: true,
|
|
122
|
+
});
|
|
123
|
+
newRl.on('line', (input) => {
|
|
124
|
+
processLine(input).catch((err) => {
|
|
125
|
+
printError(String(err));
|
|
126
|
+
prompt();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
newRl.on('close', () => {
|
|
130
|
+
if (!state.running) {
|
|
131
|
+
printGoodbye();
|
|
132
|
+
process.exit(0);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
106
135
|
console.log();
|
|
107
|
-
|
|
136
|
+
prompt();
|
|
108
137
|
}
|
|
109
138
|
else {
|
|
110
139
|
printGoodbye();
|
|
140
|
+
process.exit(0);
|
|
111
141
|
}
|
|
112
|
-
process.exit(0);
|
|
113
142
|
});
|
|
114
143
|
// Handle SIGINT (Ctrl+C)
|
|
115
144
|
process.on('SIGINT', () => {
|
package/dist/server/index.js
CHANGED
|
@@ -77,6 +77,11 @@ export class ArchiCoreServer {
|
|
|
77
77
|
timestamp: new Date().toISOString()
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
|
+
// Device authorization page for CLI
|
|
81
|
+
this.app.get('/auth/device', (_req, res) => {
|
|
82
|
+
const deviceAuthPath = path.join(__dirname, '../../public/device-auth.html');
|
|
83
|
+
res.sendFile(deviceAuthPath);
|
|
84
|
+
});
|
|
80
85
|
// SPA fallback - все остальные маршруты отдают index.html
|
|
81
86
|
this.app.get('/*splat', (_req, res) => {
|
|
82
87
|
const indexPath = path.join(__dirname, '../../public/index.html');
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import { randomBytes } from 'crypto';
|
|
8
|
+
import { AuthService } from '../services/auth-service.js';
|
|
8
9
|
const router = Router();
|
|
10
|
+
const authService = new AuthService();
|
|
9
11
|
const pendingAuths = new Map();
|
|
10
12
|
// Generate random codes
|
|
11
13
|
function generateDeviceCode() {
|
|
@@ -97,8 +99,9 @@ router.post('/token', (req, res) => {
|
|
|
97
99
|
expiresIn: 86400 * 30, // 30 days
|
|
98
100
|
user: {
|
|
99
101
|
id: auth.userId,
|
|
100
|
-
email: 'user@example.com',
|
|
101
|
-
|
|
102
|
+
email: auth.userEmail || 'user@example.com',
|
|
103
|
+
name: auth.userName,
|
|
104
|
+
tier: auth.userTier || 'free',
|
|
102
105
|
},
|
|
103
106
|
});
|
|
104
107
|
});
|
|
@@ -123,7 +126,7 @@ router.get('/verify/:userCode', (req, res) => {
|
|
|
123
126
|
* POST /api/auth/device/authorize
|
|
124
127
|
* Authorize device (called from web after user logs in)
|
|
125
128
|
*/
|
|
126
|
-
router.post('/authorize', (req, res) => {
|
|
129
|
+
router.post('/authorize', async (req, res) => {
|
|
127
130
|
const { userCode, userId, accessToken, action } = req.body;
|
|
128
131
|
if (!userCode) {
|
|
129
132
|
res.status(400).json({ error: 'invalid_request', message: 'Missing user_code' });
|
|
@@ -139,6 +142,18 @@ router.post('/authorize', (req, res) => {
|
|
|
139
142
|
res.json({ success: true, message: 'Authorization denied' });
|
|
140
143
|
return;
|
|
141
144
|
}
|
|
145
|
+
// Get user info from token
|
|
146
|
+
try {
|
|
147
|
+
const user = await authService.validateToken(accessToken);
|
|
148
|
+
if (user) {
|
|
149
|
+
auth.userEmail = user.email;
|
|
150
|
+
auth.userName = user.username;
|
|
151
|
+
auth.userTier = user.tier;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Ignore errors, use userId from request
|
|
156
|
+
}
|
|
142
157
|
// Authorize
|
|
143
158
|
auth.status = 'authorized';
|
|
144
159
|
auth.userId = userId;
|