@glassly/cli 2.0.1 → 2.0.2-beta.0
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/README.md +3 -1
- package/package.json +2 -2
- package/src/credentials.ts +21 -44
- package/src/index.ts +1 -1
package/README.md
CHANGED
|
@@ -61,4 +61,6 @@ Run `glassly <command> --help` for the full option set.
|
|
|
61
61
|
The CLI talks to the production Glassly backend and Developer Console by
|
|
62
62
|
default; nothing needs configuring. To point it at another deployment, set
|
|
63
63
|
`CLOUD_CORE_URL`, `CLOUD_CONSOLE_URL`, and that backend's public WorkOS
|
|
64
|
-
AuthKit client id in `WORKOS_CLIENT_ID`. Logins
|
|
64
|
+
AuthKit client id in `WORKOS_CLIENT_ID`. Logins and the bundle signing key are
|
|
65
|
+
stored per backend URL in `~/.glassly/cli-v2/`, readable only by your user;
|
|
66
|
+
`glassly logout` removes the login.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-beta.0",
|
|
4
4
|
"description": "The glassly command: develop, pack, release, and publish Glassly miniapps. Bun-only.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typecheck": "tsc --noEmit"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@glassly/miniapp-cli": "0.1.1",
|
|
25
|
+
"@glassly/miniapp-cli": "0.1.1-beta.0",
|
|
26
26
|
"commander": "^14.0.2",
|
|
27
27
|
"qrcode": "^1.5.4"
|
|
28
28
|
},
|
package/src/credentials.ts
CHANGED
|
@@ -36,23 +36,13 @@ export interface CliSigningKey {
|
|
|
36
36
|
createdAt: string;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
// Credentials live in a 0600 file under ~/.glassly/cli-v2, like gh and npm
|
|
40
|
+
// keep theirs. The OS keychain (Bun.secrets) was the primary store before,
|
|
41
|
+
// but on some machines a write there succeeds and the next process reads
|
|
42
|
+
// nothing back, which showed up as "login works, whoami says sign in". The
|
|
43
|
+
// keychain is still read so sessions stored there keep working.
|
|
39
44
|
export async function saveCredentials(credentials: CliCredentials): Promise<"keychain" | "file"> {
|
|
40
45
|
const payload = JSON.stringify(credentials);
|
|
41
|
-
const name = credentialName(credentials.coreUrl);
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
if (typeof Bun !== "undefined" && Bun.secrets) {
|
|
45
|
-
await Bun.secrets.set({
|
|
46
|
-
service: SERVICE,
|
|
47
|
-
name,
|
|
48
|
-
value: payload,
|
|
49
|
-
});
|
|
50
|
-
return "keychain";
|
|
51
|
-
}
|
|
52
|
-
} catch {
|
|
53
|
-
// Fall through to file storage.
|
|
54
|
-
}
|
|
55
|
-
|
|
56
46
|
mkdirSync(CREDS_DIR, { recursive: true });
|
|
57
47
|
writeFileSync(credentialsFile(credentials.coreUrl), `${payload}\n`, { mode: 0o600 });
|
|
58
48
|
return "file";
|
|
@@ -124,21 +114,6 @@ export async function clearCredentials(coreUrl?: string): Promise<void> {
|
|
|
124
114
|
|
|
125
115
|
export async function saveSigningKey(key: CliSigningKey): Promise<"keychain" | "file"> {
|
|
126
116
|
const payload = JSON.stringify(key);
|
|
127
|
-
const name = credentialName(key.coreUrl);
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
if (typeof Bun !== "undefined" && Bun.secrets) {
|
|
131
|
-
await Bun.secrets.set({
|
|
132
|
-
service: SIGNING_KEY_SERVICE,
|
|
133
|
-
name,
|
|
134
|
-
value: payload,
|
|
135
|
-
});
|
|
136
|
-
return "keychain";
|
|
137
|
-
}
|
|
138
|
-
} catch {
|
|
139
|
-
// Fall through to file storage.
|
|
140
|
-
}
|
|
141
|
-
|
|
142
117
|
mkdirSync(CREDS_DIR, { recursive: true });
|
|
143
118
|
writeFileSync(signingKeyFile(key.coreUrl), `${payload}\n`, { mode: 0o600 });
|
|
144
119
|
return "file";
|
|
@@ -146,6 +121,14 @@ export async function saveSigningKey(key: CliSigningKey): Promise<"keychain" | "
|
|
|
146
121
|
|
|
147
122
|
export async function loadSigningKey(coreUrl: string): Promise<CliSigningKey | null> {
|
|
148
123
|
const targetCoreUrl = normalizeCoreUrl(coreUrl);
|
|
124
|
+
try {
|
|
125
|
+
const path = signingKeyFile(targetCoreUrl);
|
|
126
|
+
if (existsSync(path)) return JSON.parse(readFileSync(path, "utf8")) as CliSigningKey;
|
|
127
|
+
} catch {
|
|
128
|
+
// Treat corrupt key storage as missing.
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Keys created by earlier versions sit in the OS keychain.
|
|
149
132
|
try {
|
|
150
133
|
if (typeof Bun !== "undefined" && Bun.secrets) {
|
|
151
134
|
const value = await Bun.secrets.get({
|
|
@@ -158,17 +141,18 @@ export async function loadSigningKey(coreUrl: string): Promise<CliSigningKey | n
|
|
|
158
141
|
// Fall through.
|
|
159
142
|
}
|
|
160
143
|
|
|
161
|
-
try {
|
|
162
|
-
const path = signingKeyFile(targetCoreUrl);
|
|
163
|
-
if (existsSync(path)) return JSON.parse(readFileSync(path, "utf8")) as CliSigningKey;
|
|
164
|
-
} catch {
|
|
165
|
-
// Treat corrupt key storage as missing.
|
|
166
|
-
}
|
|
167
|
-
|
|
168
144
|
return null;
|
|
169
145
|
}
|
|
170
146
|
|
|
171
147
|
async function loadScopedCredentials(coreUrl: string): Promise<CliCredentials | null> {
|
|
148
|
+
try {
|
|
149
|
+
const path = credentialsFile(coreUrl);
|
|
150
|
+
if (existsSync(path)) return JSON.parse(readFileSync(path, "utf8")) as CliCredentials;
|
|
151
|
+
} catch {
|
|
152
|
+
// Treat corrupt credentials as logged out.
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Sessions stored by earlier versions sit in the OS keychain.
|
|
172
156
|
try {
|
|
173
157
|
if (typeof Bun !== "undefined" && Bun.secrets) {
|
|
174
158
|
const value = await Bun.secrets.get({
|
|
@@ -181,13 +165,6 @@ async function loadScopedCredentials(coreUrl: string): Promise<CliCredentials |
|
|
|
181
165
|
// Fall through.
|
|
182
166
|
}
|
|
183
167
|
|
|
184
|
-
try {
|
|
185
|
-
const path = credentialsFile(coreUrl);
|
|
186
|
-
if (existsSync(path)) return JSON.parse(readFileSync(path, "utf8")) as CliCredentials;
|
|
187
|
-
} catch {
|
|
188
|
-
// Treat corrupt credentials as logged out.
|
|
189
|
-
}
|
|
190
|
-
|
|
191
168
|
return null;
|
|
192
169
|
}
|
|
193
170
|
|
package/src/index.ts
CHANGED
|
@@ -135,7 +135,7 @@ program
|
|
|
135
135
|
});
|
|
136
136
|
console.log(`Signed in as ${token.user.email}`);
|
|
137
137
|
if (token.organization_id) console.log(`Organization: ${token.organization_id}`);
|
|
138
|
-
console.log(`Credentials stored in ${storage === "keychain" ? "OS keychain" : "~/.glassly/cli-v2"}`);
|
|
138
|
+
console.log(`Credentials stored in ${storage === "keychain" ? "the OS keychain" : "~/.glassly/cli-v2 (readable only by you)"}`);
|
|
139
139
|
return;
|
|
140
140
|
}
|
|
141
141
|
|