@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@l4yercak3/cli",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Icing on the L4yercak3 - The sweet finishing touch for your Layer Cake integration",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -129,7 +129,8 @@ class BackendClient {
129
129
  * @returns {string} The login URL
130
130
  */
131
131
  getLoginUrl(state, provider = null) {
132
- const callbackUrl = 'http://localhost:3000/callback';
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
@@ -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, 'http://localhost:3000');
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.listen(3000, 'localhost', () => {
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
- console.log(chalk.green(' āœ… You are already logged in'));
133
- if (session.email) {
134
- console.log(chalk.gray(` Email: ${session.email}`));
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
- // Still offer the setup wizard
139
- await promptSetupWizard();
140
- return;
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:3000/callback'));
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(() => {