claude-remote-cli 3.9.0 → 3.9.1
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 +5 -0
- 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
|
@@ -160,6 +160,11 @@ async function main() {
|
|
|
160
160
|
catch (err) {
|
|
161
161
|
console.warn('Analytics disabled: failed to initialize:', err instanceof Error ? err.message : err);
|
|
162
162
|
}
|
|
163
|
+
if (config.pinHash && auth.isLegacyHash(config.pinHash)) {
|
|
164
|
+
console.log('Migrating legacy PIN hash to scrypt. You will need to set a new PIN.');
|
|
165
|
+
delete config.pinHash;
|
|
166
|
+
saveConfig(CONFIG_PATH, config);
|
|
167
|
+
}
|
|
163
168
|
if (!config.pinHash) {
|
|
164
169
|
const pin = await promptPin('Set up a PIN for claude-remote-cli:');
|
|
165
170
|
config.pinHash = await auth.hashPin(pin);
|
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();
|