whydid 1.0.0 → 1.0.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/licensing/config.js
CHANGED
|
@@ -5,13 +5,13 @@ import { HttpLicenseApiClient } from "./license-client.js";
|
|
|
5
5
|
import { createLicenseStore } from "./license-store.js";
|
|
6
6
|
import { getMachineId } from "./machine-id.js";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* The real production Ed25519 public key, matching the private key held
|
|
9
|
+
* only in license-server's deployed .env (LICENSE_ED25519_PRIVATE_KEY) —
|
|
10
|
+
* generated once via license-server/scripts/generate-keypair.ts. Every
|
|
11
|
+
* signed license this public key verifies was signed by that exact
|
|
12
|
+
* deployment; swapping it invalidates every previously-issued license.
|
|
13
13
|
*/
|
|
14
|
-
export const PUBLIC_KEY_DER_BASE64 = process.env.WHYDID_LICENSE_PUBLIC_KEY ?? "
|
|
14
|
+
export const PUBLIC_KEY_DER_BASE64 = process.env.WHYDID_LICENSE_PUBLIC_KEY ?? "MCowBQYDK2VwAyEA2CpLqf2+q26q6q1k77bbJZYvQ1otG4E6iY19e+KNogc=";
|
|
15
15
|
export const LICENSE_API_URL = process.env.WHYDID_LICENSE_API_URL ?? "https://license.whydid.dev";
|
|
16
16
|
export const PRICING_URL = "https://whydid.dev/pricing";
|
|
17
17
|
function globalLicenseDir() {
|
|
@@ -3,6 +3,24 @@ import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
const SERVICE_NAME = "whydid-license";
|
|
5
5
|
const ACCOUNT_NAME = "license";
|
|
6
|
+
async function loadRealKeytar() {
|
|
7
|
+
return import("@napi-rs/keyring/keytar.js");
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The OS keychain prompt (e.g. macOS's "wants to use your confidential
|
|
11
|
+
* information") asks for the user's own Mac login password, not anything
|
|
12
|
+
* whydid-specific — but denying/canceling it throws a raw native error
|
|
13
|
+
* ("User canceled the operation.") straight out of @napi-rs/keyring. Left
|
|
14
|
+
* unwrapped, that string reaches the user verbatim with no context. This
|
|
15
|
+
* wraps ANY keychain-access failure (denied, canceled, or an unexpected
|
|
16
|
+
* platform error) in one clear, actionable message.
|
|
17
|
+
*/
|
|
18
|
+
function wrapKeychainError(err) {
|
|
19
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
20
|
+
return new Error(`whydid couldn't access your saved license in the system keychain (${raw}). ` +
|
|
21
|
+
`This is asking for your Mac's own login password, not a whydid password — ` +
|
|
22
|
+
`run the command again and click "Allow" (or "Always Allow") when prompted.`);
|
|
23
|
+
}
|
|
6
24
|
/**
|
|
7
25
|
* OS keychain (macOS Keychain / Windows Credential Manager / Linux Secret
|
|
8
26
|
* Service), via @napi-rs/keyring's keytar-compatible API — the maintained
|
|
@@ -12,13 +30,28 @@ const ACCOUNT_NAME = "license";
|
|
|
12
30
|
* this platform/architecture.
|
|
13
31
|
*/
|
|
14
32
|
export class KeychainLicenseStore {
|
|
33
|
+
loadKeytar;
|
|
34
|
+
constructor(loadKeytar = loadRealKeytar) {
|
|
35
|
+
this.loadKeytar = loadKeytar;
|
|
36
|
+
}
|
|
15
37
|
async save(signed) {
|
|
16
|
-
const { setPassword } = await
|
|
17
|
-
|
|
38
|
+
const { setPassword } = await this.loadKeytar();
|
|
39
|
+
try {
|
|
40
|
+
await setPassword(SERVICE_NAME, ACCOUNT_NAME, JSON.stringify(signed));
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
throw wrapKeychainError(err);
|
|
44
|
+
}
|
|
18
45
|
}
|
|
19
46
|
async load() {
|
|
20
|
-
const { getPassword } = await
|
|
21
|
-
|
|
47
|
+
const { getPassword } = await this.loadKeytar();
|
|
48
|
+
let raw;
|
|
49
|
+
try {
|
|
50
|
+
raw = await getPassword(SERVICE_NAME, ACCOUNT_NAME);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
throw wrapKeychainError(err);
|
|
54
|
+
}
|
|
22
55
|
if (!raw)
|
|
23
56
|
return null;
|
|
24
57
|
try {
|
|
@@ -29,7 +62,7 @@ export class KeychainLicenseStore {
|
|
|
29
62
|
}
|
|
30
63
|
}
|
|
31
64
|
async clear() {
|
|
32
|
-
const { deletePassword } = await
|
|
65
|
+
const { deletePassword } = await this.loadKeytar();
|
|
33
66
|
await deletePassword(SERVICE_NAME, ACCOUNT_NAME).catch(() => false);
|
|
34
67
|
}
|
|
35
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whydid",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"description": "A local-first AI coding time machine — captures meaningful changes, reasoning, and session context so you can see what happened across your coding sessions, even days later.",
|