claude-remote-cli 3.9.0 → 3.9.2
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/server/auth.js +4 -2
- package/dist/server/index.js +15 -1
- package/dist/test/auth.test.js +12 -1
- package/package.json +1 -1
package/dist/server/auth.js
CHANGED
|
@@ -26,8 +26,7 @@ export async function verifyPin(pin, hash) {
|
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
// Legacy bcrypt hashes
|
|
30
|
-
console.warn('[auth] Legacy bcrypt PIN hash detected. Delete pinHash from config and restart to set a new PIN.');
|
|
29
|
+
// Legacy bcrypt hashes are migrated at startup; if one reaches here, reject it
|
|
31
30
|
return false;
|
|
32
31
|
}
|
|
33
32
|
export function isRateLimited(ip) {
|
|
@@ -56,6 +55,9 @@ export function clearRateLimit(ip) {
|
|
|
56
55
|
export function generateCookieToken() {
|
|
57
56
|
return crypto.randomBytes(32).toString('hex');
|
|
58
57
|
}
|
|
58
|
+
export function isLegacyHash(hash) {
|
|
59
|
+
return !!hash && !hash.startsWith('scrypt:');
|
|
60
|
+
}
|
|
59
61
|
export function _resetForTesting() {
|
|
60
62
|
attemptMap.clear();
|
|
61
63
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
1
2
|
import fs from 'node:fs';
|
|
2
3
|
import http from 'node:http';
|
|
3
4
|
import os from 'node:os';
|
|
@@ -160,8 +161,21 @@ async function main() {
|
|
|
160
161
|
catch (err) {
|
|
161
162
|
console.warn('Analytics disabled: failed to initialize:', err instanceof Error ? err.message : err);
|
|
162
163
|
}
|
|
164
|
+
if (config.pinHash && auth.isLegacyHash(config.pinHash)) {
|
|
165
|
+
console.log('Migrating legacy PIN hash to scrypt. You will need to set a new PIN.');
|
|
166
|
+
delete config.pinHash;
|
|
167
|
+
saveConfig(CONFIG_PATH, config);
|
|
168
|
+
}
|
|
163
169
|
if (!config.pinHash) {
|
|
164
|
-
|
|
170
|
+
let pin;
|
|
171
|
+
if (process.stdin.isTTY) {
|
|
172
|
+
pin = await promptPin('Set up a PIN for claude-remote-cli:');
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
pin = crypto.randomInt(100000, 999999).toString();
|
|
176
|
+
console.log(`No interactive terminal detected. Generated PIN: ${pin}`);
|
|
177
|
+
console.log('Change it by deleting pinHash from your config file and restarting interactively.');
|
|
178
|
+
}
|
|
165
179
|
config.pinHash = await auth.hashPin(pin);
|
|
166
180
|
saveConfig(CONFIG_PATH, config);
|
|
167
181
|
console.log('PIN set successfully.');
|
package/dist/test/auth.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test } from 'node:test';
|
|
2
2
|
import assert from 'node:assert';
|
|
3
|
-
import { hashPin, verifyPin, isRateLimited, recordFailedAttempt, generateCookieToken, _resetForTesting, } from '../server/auth.js';
|
|
3
|
+
import { hashPin, verifyPin, isLegacyHash, isRateLimited, recordFailedAttempt, generateCookieToken, _resetForTesting, } from '../server/auth.js';
|
|
4
4
|
test('hashPin returns scrypt hash with expected format', async () => {
|
|
5
5
|
_resetForTesting();
|
|
6
6
|
const hash = await hashPin('1234');
|
|
@@ -77,6 +77,17 @@ test('hashPin produces unique salts', async () => {
|
|
|
77
77
|
assert.strictEqual(await verifyPin('1234', hash1), true);
|
|
78
78
|
assert.strictEqual(await verifyPin('1234', hash2), true);
|
|
79
79
|
});
|
|
80
|
+
test('isLegacyHash returns true for bcrypt hashes', () => {
|
|
81
|
+
assert.strictEqual(isLegacyHash('$2b$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ012'), true);
|
|
82
|
+
assert.strictEqual(isLegacyHash('$2a$10$someotherbcrypthashvalue'), true);
|
|
83
|
+
});
|
|
84
|
+
test('isLegacyHash returns false for scrypt hashes', async () => {
|
|
85
|
+
const hash = await hashPin('1234');
|
|
86
|
+
assert.strictEqual(isLegacyHash(hash), false);
|
|
87
|
+
});
|
|
88
|
+
test('isLegacyHash returns false for empty string', () => {
|
|
89
|
+
assert.strictEqual(isLegacyHash(''), false);
|
|
90
|
+
});
|
|
80
91
|
test('generateCookieToken returns non-empty string', () => {
|
|
81
92
|
_resetForTesting();
|
|
82
93
|
const token = generateCookieToken();
|