nstantpage-agent 0.5.30 → 0.5.32
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/dist/commands/login.js +53 -10
- package/dist/commands/start.js +15 -0
- package/package.json +1 -1
package/dist/commands/login.js
CHANGED
|
@@ -49,16 +49,30 @@ export async function loginCommand(options = {}) {
|
|
|
49
49
|
// Check if already logged in (unless --force)
|
|
50
50
|
const existingToken = conf.get('token');
|
|
51
51
|
if (existingToken && !options.force) {
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
// Check if existing token is expired
|
|
53
|
+
const payload = decodeJwtPayload(existingToken);
|
|
54
|
+
const isExpired = payload?.exp && payload.exp < Date.now() / 1000;
|
|
55
|
+
if (!isExpired) {
|
|
56
|
+
const email = conf.get('email') || getEmailFromToken(existingToken);
|
|
57
|
+
const storedGateway = conf.get('gatewayUrl') || 'wss://webprev.live';
|
|
58
|
+
const isStoredLocal = /^wss?:\/\/(localhost|127\.0\.0\.1)/.test(storedGateway);
|
|
59
|
+
console.log(chalk.green('✓ Already authenticated'));
|
|
60
|
+
if (email)
|
|
61
|
+
console.log(chalk.gray(` Account: ${email}`));
|
|
62
|
+
console.log(chalk.gray(` Server: ${isStoredLocal ? 'localhost (dev)' : 'nstantpage.com'}`));
|
|
63
|
+
console.log(chalk.gray(' Run "nstantpage login --force" to re-authenticate'));
|
|
64
|
+
console.log(chalk.gray(' Run "nstantpage logout" to sign out.'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Token expired — clear it and proceed with fresh login
|
|
68
|
+
console.log(chalk.yellow('⚠ Your token has expired. Starting fresh login...\n'));
|
|
69
|
+
conf.delete('token');
|
|
70
|
+
conf.delete('email');
|
|
71
|
+
}
|
|
72
|
+
// If --force, clear old token so we start fresh
|
|
73
|
+
if (options.force && existingToken) {
|
|
74
|
+
conf.delete('token');
|
|
75
|
+
conf.delete('email');
|
|
62
76
|
}
|
|
63
77
|
const frontendUrl = resolveFrontendUrl(options.gateway);
|
|
64
78
|
const isLocal = frontendUrl.includes('localhost');
|
|
@@ -79,6 +93,35 @@ export async function loginCommand(options = {}) {
|
|
|
79
93
|
const url = new URL(req.url, `http://localhost:${callbackPort}`);
|
|
80
94
|
const token = url.searchParams.get('token');
|
|
81
95
|
if (token) {
|
|
96
|
+
// Validate token is not expired before accepting it
|
|
97
|
+
const payload = decodeJwtPayload(token);
|
|
98
|
+
if (payload?.exp && payload.exp < Date.now() / 1000) {
|
|
99
|
+
// Token is expired — clear browser storage and redirect to sign-in
|
|
100
|
+
// After signing in, the browser will get a fresh token and revisit /auth/agent
|
|
101
|
+
const agentCallbackUrl = `http://localhost:${callbackPort}/callback`;
|
|
102
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
103
|
+
res.end(`
|
|
104
|
+
<html>
|
|
105
|
+
<body style="font-family: sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: #0f172a; color: #f8fafc;">
|
|
106
|
+
<div style="text-align: center;">
|
|
107
|
+
<h1 style="color: #eab308;">⟳ Session expired — signing you in...</h1>
|
|
108
|
+
<p style="color: #94a3b8;">Redirecting to nstantpage.com...</p>
|
|
109
|
+
</div>
|
|
110
|
+
<script>
|
|
111
|
+
// Clear the expired token from browser localStorage
|
|
112
|
+
localStorage.removeItem('auth_token');
|
|
113
|
+
localStorage.removeItem('auth_user');
|
|
114
|
+
// Store the agent callback URL for after sign-in
|
|
115
|
+
sessionStorage.setItem('agentCallbackUrl', '${agentCallbackUrl}');
|
|
116
|
+
// Redirect to sign-in, which will redirect back to /auth/agent after login
|
|
117
|
+
window.location.href = '${frontendUrl}/sign-in?returnUrl=/auth/agent';
|
|
118
|
+
</script>
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
`);
|
|
122
|
+
// Don't close server — wait for a valid token after re-login
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
82
125
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
83
126
|
res.end(`
|
|
84
127
|
<html>
|
package/dist/commands/start.js
CHANGED
|
@@ -194,6 +194,21 @@ export async function startCommand(directory, options) {
|
|
|
194
194
|
if (!token && isLocalGateway) {
|
|
195
195
|
token = 'local-dev';
|
|
196
196
|
}
|
|
197
|
+
// Check token expiry before connecting
|
|
198
|
+
if (token && token !== 'local-dev') {
|
|
199
|
+
try {
|
|
200
|
+
const parts = token.split('.');
|
|
201
|
+
if (parts.length === 3) {
|
|
202
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString('utf-8'));
|
|
203
|
+
if (payload.exp && payload.exp < Date.now() / 1000) {
|
|
204
|
+
console.log(chalk.red('✗ Your authentication token has expired.'));
|
|
205
|
+
console.log(chalk.gray(' Run "nstantpage login" to re-authenticate.'));
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch { }
|
|
211
|
+
}
|
|
197
212
|
// Determine project ID (optional — without it, agent enters standby mode)
|
|
198
213
|
// Only use explicitly passed --project-id, never fall back to stored value
|
|
199
214
|
let projectId = options.projectId;
|
package/package.json
CHANGED