@l4yercak3/cli 1.1.3 ā 1.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.
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"Bash(gh repo create:*)",
|
|
15
15
|
"Bash(npm whoami:*)",
|
|
16
16
|
"Bash(npm pkg fix:*)",
|
|
17
|
-
"Bash(git push:*)"
|
|
17
|
+
"Bash(git push:*)",
|
|
18
|
+
"Bash(session\" errors when trying to use features.\n\nNow the login command validates the session with the backend first.\nIf validation fails, it clears the local session and prompts for\nfresh login, avoiding the confusing loop.\n\nš¤ Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
|
|
18
19
|
]
|
|
19
20
|
}
|
|
20
21
|
}
|
package/package.json
CHANGED
|
@@ -129,7 +129,8 @@ class BackendClient {
|
|
|
129
129
|
* @returns {string} The login URL
|
|
130
130
|
*/
|
|
131
131
|
getLoginUrl(state, provider = null) {
|
|
132
|
-
|
|
132
|
+
// Use port 3333 to avoid conflicts with Next.js dev server (port 3000)
|
|
133
|
+
const callbackUrl = 'http://localhost:3333/callback';
|
|
133
134
|
|
|
134
135
|
if (provider) {
|
|
135
136
|
// Direct OAuth provider URL
|
package/src/commands/login.js
CHANGED
|
@@ -39,6 +39,9 @@ function generateRetroPage({ title, icon, heading, headingColor, message, submes
|
|
|
39
39
|
</html>`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// CLI callback port - different from Next.js dev server (3000)
|
|
43
|
+
const CLI_CALLBACK_PORT = 3333;
|
|
44
|
+
|
|
42
45
|
/**
|
|
43
46
|
* Start local server to receive OAuth callback
|
|
44
47
|
* @param {string} expectedState - The state token to verify against
|
|
@@ -48,7 +51,7 @@ function startCallbackServer(expectedState) {
|
|
|
48
51
|
const http = require('http');
|
|
49
52
|
|
|
50
53
|
const server = http.createServer((req, res) => {
|
|
51
|
-
const url = new URL(req.url,
|
|
54
|
+
const url = new URL(req.url, `http://localhost:${CLI_CALLBACK_PORT}`);
|
|
52
55
|
|
|
53
56
|
if (url.pathname === '/callback') {
|
|
54
57
|
const token = url.searchParams.get('token');
|
|
@@ -104,7 +107,16 @@ function startCallbackServer(expectedState) {
|
|
|
104
107
|
}
|
|
105
108
|
});
|
|
106
109
|
|
|
107
|
-
server
|
|
110
|
+
// Handle server errors (e.g., port already in use)
|
|
111
|
+
server.on('error', (err) => {
|
|
112
|
+
if (err.code === 'EADDRINUSE') {
|
|
113
|
+
reject(new Error(`Port ${CLI_CALLBACK_PORT} is already in use. Please close any other l4yercak3 processes and try again.`));
|
|
114
|
+
} else {
|
|
115
|
+
reject(err);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
server.listen(CLI_CALLBACK_PORT, 'localhost', () => {
|
|
108
120
|
console.log(chalk.gray(' Waiting for authentication...'));
|
|
109
121
|
});
|
|
110
122
|
|
|
@@ -121,7 +133,7 @@ function startCallbackServer(expectedState) {
|
|
|
121
133
|
*/
|
|
122
134
|
async function handleLogin() {
|
|
123
135
|
try {
|
|
124
|
-
// Check if already logged in
|
|
136
|
+
// Check if already logged in (local check)
|
|
125
137
|
if (configManager.isLoggedIn()) {
|
|
126
138
|
const session = configManager.getSession();
|
|
127
139
|
|
|
@@ -129,15 +141,26 @@ async function handleLogin() {
|
|
|
129
141
|
console.log('');
|
|
130
142
|
showLogo(false);
|
|
131
143
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
console.log(chalk.gray(` Session expires: ${new Date(session.expiresAt).toLocaleString()}\n`));
|
|
144
|
+
// Validate session with backend to ensure it's actually valid
|
|
145
|
+
console.log(chalk.gray(' Validating session with backend...'));
|
|
146
|
+
const validationResult = await backendClient.validateSession();
|
|
137
147
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
148
|
+
if (validationResult) {
|
|
149
|
+
console.log(chalk.green(' ā
You are already logged in'));
|
|
150
|
+
if (session.email) {
|
|
151
|
+
console.log(chalk.gray(` Email: ${session.email}`));
|
|
152
|
+
}
|
|
153
|
+
console.log(chalk.gray(` Session expires: ${new Date(session.expiresAt).toLocaleString()}\n`));
|
|
154
|
+
|
|
155
|
+
// Still offer the setup wizard
|
|
156
|
+
await promptSetupWizard();
|
|
157
|
+
return;
|
|
158
|
+
} else {
|
|
159
|
+
// Session is invalid on backend - clear it and proceed to login
|
|
160
|
+
console.log(chalk.yellow(' ā ļø Your session has expired or is invalid'));
|
|
161
|
+
console.log(chalk.gray(' Starting fresh login...\n'));
|
|
162
|
+
configManager.clearSession();
|
|
163
|
+
}
|
|
141
164
|
}
|
|
142
165
|
|
|
143
166
|
console.log(chalk.cyan(' š Opening browser for authentication...\n'));
|
|
@@ -290,7 +290,7 @@ describe('BackendClient', () => {
|
|
|
290
290
|
const state = 'test-state-token';
|
|
291
291
|
const url = BackendClient.getLoginUrl(state, 'github');
|
|
292
292
|
|
|
293
|
-
expect(url).toContain(encodeURIComponent('http://localhost:
|
|
293
|
+
expect(url).toContain(encodeURIComponent('http://localhost:3333/callback'));
|
|
294
294
|
});
|
|
295
295
|
});
|
|
296
296
|
|
|
@@ -57,6 +57,8 @@ describe('Login Command', () => {
|
|
|
57
57
|
|
|
58
58
|
configManager.getSession.mockReturnValue(null);
|
|
59
59
|
backendClient.getLoginUrl.mockReturnValue('https://backend.test.com/auth/cli-login');
|
|
60
|
+
// Mock validateSession to return valid result by default
|
|
61
|
+
backendClient.validateSession.mockResolvedValue({ valid: true, userId: 'user-123' });
|
|
60
62
|
});
|
|
61
63
|
|
|
62
64
|
afterEach(() => {
|