oauth.do 0.1.7 → 0.1.10
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/cli.js +157 -69
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +70 -41
- package/dist/index.js +30 -49
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.js +624 -0
- package/dist/node.js.map +1 -0
- package/package.json +5 -1
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,10 @@ var __esm = (fn, res) => function __init() {
|
|
|
11
11
|
var __commonJS = (cb, mod) => function __require() {
|
|
12
12
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
13
|
};
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
14
18
|
var __copyProps = (to, from, except, desc) => {
|
|
15
19
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
20
|
for (let key of __getOwnPropNames(from))
|
|
@@ -29,23 +33,33 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
33
|
));
|
|
30
34
|
|
|
31
35
|
// src/storage.ts
|
|
36
|
+
var storage_exports = {};
|
|
37
|
+
__export(storage_exports, {
|
|
38
|
+
CompositeTokenStorage: () => CompositeTokenStorage,
|
|
39
|
+
FileTokenStorage: () => FileTokenStorage,
|
|
40
|
+
KeychainTokenStorage: () => KeychainTokenStorage,
|
|
41
|
+
LocalStorageTokenStorage: () => LocalStorageTokenStorage,
|
|
42
|
+
MemoryTokenStorage: () => MemoryTokenStorage,
|
|
43
|
+
SecureFileTokenStorage: () => SecureFileTokenStorage,
|
|
44
|
+
createSecureStorage: () => createSecureStorage
|
|
45
|
+
});
|
|
32
46
|
function isNode() {
|
|
33
47
|
return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
34
48
|
}
|
|
35
|
-
function
|
|
49
|
+
function getEnv2(key) {
|
|
36
50
|
if (typeof process !== "undefined" && process.env?.[key]) return process.env[key];
|
|
37
51
|
return void 0;
|
|
38
52
|
}
|
|
39
53
|
function createSecureStorage() {
|
|
40
54
|
if (isNode()) {
|
|
41
|
-
return new
|
|
55
|
+
return new SecureFileTokenStorage();
|
|
42
56
|
}
|
|
43
57
|
if (typeof localStorage !== "undefined") {
|
|
44
58
|
return new LocalStorageTokenStorage();
|
|
45
59
|
}
|
|
46
60
|
return new MemoryTokenStorage();
|
|
47
61
|
}
|
|
48
|
-
var KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, KeychainTokenStorage, SecureFileTokenStorage, MemoryTokenStorage, LocalStorageTokenStorage, CompositeTokenStorage;
|
|
62
|
+
var KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, KeychainTokenStorage, SecureFileTokenStorage, FileTokenStorage, MemoryTokenStorage, LocalStorageTokenStorage, CompositeTokenStorage;
|
|
49
63
|
var init_storage = __esm({
|
|
50
64
|
"src/storage.ts"() {
|
|
51
65
|
KEYCHAIN_SERVICE = "oauth.do";
|
|
@@ -67,7 +81,7 @@ var init_storage = __esm({
|
|
|
67
81
|
const keytarModule = imported.default || imported;
|
|
68
82
|
this.keytar = keytarModule;
|
|
69
83
|
if (typeof this.keytar.getPassword !== "function") {
|
|
70
|
-
if (
|
|
84
|
+
if (getEnv2("DEBUG")) {
|
|
71
85
|
console.warn("Keytar module loaded but getPassword is not a function:", Object.keys(this.keytar));
|
|
72
86
|
}
|
|
73
87
|
this.keytar = null;
|
|
@@ -75,7 +89,7 @@ var init_storage = __esm({
|
|
|
75
89
|
}
|
|
76
90
|
return this.keytar;
|
|
77
91
|
} catch (error) {
|
|
78
|
-
if (
|
|
92
|
+
if (getEnv2("DEBUG")) {
|
|
79
93
|
console.warn("Keychain storage not available:", error);
|
|
80
94
|
}
|
|
81
95
|
return null;
|
|
@@ -90,7 +104,7 @@ var init_storage = __esm({
|
|
|
90
104
|
const token = await keytar.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
91
105
|
return token;
|
|
92
106
|
} catch (error) {
|
|
93
|
-
if (
|
|
107
|
+
if (getEnv2("DEBUG")) {
|
|
94
108
|
console.warn("Failed to get token from keychain:", error);
|
|
95
109
|
}
|
|
96
110
|
return null;
|
|
@@ -132,7 +146,7 @@ var init_storage = __esm({
|
|
|
132
146
|
await keytar.getPassword(KEYCHAIN_SERVICE, "__test__");
|
|
133
147
|
return true;
|
|
134
148
|
} catch (error) {
|
|
135
|
-
if (
|
|
149
|
+
if (getEnv2("DEBUG")) {
|
|
136
150
|
console.warn("Keychain not available:", error);
|
|
137
151
|
}
|
|
138
152
|
return false;
|
|
@@ -163,7 +177,7 @@ var init_storage = __esm({
|
|
|
163
177
|
const fs = await import('fs/promises');
|
|
164
178
|
const stats = await fs.stat(this.tokenPath);
|
|
165
179
|
const mode = stats.mode & 511;
|
|
166
|
-
if (mode !== 384 &&
|
|
180
|
+
if (mode !== 384 && getEnv2("DEBUG")) {
|
|
167
181
|
console.warn(
|
|
168
182
|
`Warning: Token file has insecure permissions (${mode.toString(8)}). Expected 600. Run: chmod 600 ${this.tokenPath}`
|
|
169
183
|
);
|
|
@@ -196,6 +210,63 @@ var init_storage = __esm({
|
|
|
196
210
|
} catch {
|
|
197
211
|
}
|
|
198
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Get information about the storage backend
|
|
215
|
+
*/
|
|
216
|
+
async getStorageInfo() {
|
|
217
|
+
await this.init();
|
|
218
|
+
return { type: "file", secure: true, path: this.tokenPath };
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
FileTokenStorage = class {
|
|
222
|
+
tokenPath = null;
|
|
223
|
+
configDir = null;
|
|
224
|
+
initialized = false;
|
|
225
|
+
async init() {
|
|
226
|
+
if (this.initialized) return this.tokenPath !== null;
|
|
227
|
+
this.initialized = true;
|
|
228
|
+
if (!isNode()) return false;
|
|
229
|
+
try {
|
|
230
|
+
const os = await import('os');
|
|
231
|
+
const path = await import('path');
|
|
232
|
+
this.configDir = path.join(os.homedir(), ".oauth.do");
|
|
233
|
+
this.tokenPath = path.join(this.configDir, "token");
|
|
234
|
+
return true;
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async getToken() {
|
|
240
|
+
if (!await this.init() || !this.tokenPath) return null;
|
|
241
|
+
try {
|
|
242
|
+
const fs = await import('fs/promises');
|
|
243
|
+
const token = await fs.readFile(this.tokenPath, "utf-8");
|
|
244
|
+
return token.trim();
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async setToken(token) {
|
|
250
|
+
if (!await this.init() || !this.tokenPath || !this.configDir) {
|
|
251
|
+
throw new Error("File storage not available");
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
const fs = await import('fs/promises');
|
|
255
|
+
await fs.mkdir(this.configDir, { recursive: true });
|
|
256
|
+
await fs.writeFile(this.tokenPath, token, "utf-8");
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error("Failed to save token:", error);
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async removeToken() {
|
|
263
|
+
if (!await this.init() || !this.tokenPath) return;
|
|
264
|
+
try {
|
|
265
|
+
const fs = await import('fs/promises');
|
|
266
|
+
await fs.unlink(this.tokenPath);
|
|
267
|
+
} catch {
|
|
268
|
+
}
|
|
269
|
+
}
|
|
199
270
|
};
|
|
200
271
|
MemoryTokenStorage = class {
|
|
201
272
|
token = null;
|
|
@@ -263,7 +334,7 @@ var init_storage = __esm({
|
|
|
263
334
|
try {
|
|
264
335
|
await this.keychainStorage.setToken(fileToken);
|
|
265
336
|
await this.fileStorage.removeToken();
|
|
266
|
-
if (
|
|
337
|
+
if (getEnv2("DEBUG")) {
|
|
267
338
|
console.log("Migrated token from file to keychain");
|
|
268
339
|
}
|
|
269
340
|
} catch {
|
|
@@ -298,7 +369,7 @@ var require_package = __commonJS({
|
|
|
298
369
|
"package.json"(exports$1, module) {
|
|
299
370
|
module.exports = {
|
|
300
371
|
name: "oauth.do",
|
|
301
|
-
version: "0.1.
|
|
372
|
+
version: "0.1.10",
|
|
302
373
|
description: "OAuth authentication SDK and CLI for .do Platform",
|
|
303
374
|
type: "module",
|
|
304
375
|
main: "./dist/index.js",
|
|
@@ -311,6 +382,10 @@ var require_package = __commonJS({
|
|
|
311
382
|
types: "./dist/index.d.ts",
|
|
312
383
|
import: "./dist/index.js"
|
|
313
384
|
},
|
|
385
|
+
"./node": {
|
|
386
|
+
types: "./dist/node.d.ts",
|
|
387
|
+
import: "./dist/node.js"
|
|
388
|
+
},
|
|
314
389
|
"./mdx/*": "./src/mdx/*"
|
|
315
390
|
},
|
|
316
391
|
files: [
|
|
@@ -476,41 +551,22 @@ async function pollForTokens(deviceCode, interval = 5, expiresIn = 600) {
|
|
|
476
551
|
}
|
|
477
552
|
|
|
478
553
|
// src/auth.ts
|
|
479
|
-
function
|
|
554
|
+
async function resolveSecret(value) {
|
|
555
|
+
if (!value) return null;
|
|
556
|
+
if (typeof value === "string") return value;
|
|
557
|
+
if (typeof value === "object" && typeof value.get === "function") {
|
|
558
|
+
return await value.get();
|
|
559
|
+
}
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
function getEnv3(key) {
|
|
480
563
|
if (globalThis[key]) return globalThis[key];
|
|
481
564
|
if (typeof process !== "undefined" && process.env?.[key]) return process.env[key];
|
|
482
565
|
return void 0;
|
|
483
566
|
}
|
|
484
|
-
async function auth(token) {
|
|
485
|
-
const config = getConfig();
|
|
486
|
-
const authToken = token || getEnv2("DO_TOKEN") || "";
|
|
487
|
-
if (!authToken) {
|
|
488
|
-
return { user: null };
|
|
489
|
-
}
|
|
490
|
-
try {
|
|
491
|
-
const response = await config.fetch(`${config.apiUrl}/me`, {
|
|
492
|
-
method: "GET",
|
|
493
|
-
headers: {
|
|
494
|
-
"Authorization": `Bearer ${authToken}`,
|
|
495
|
-
"Content-Type": "application/json"
|
|
496
|
-
}
|
|
497
|
-
});
|
|
498
|
-
if (!response.ok) {
|
|
499
|
-
if (response.status === 401) {
|
|
500
|
-
return { user: null };
|
|
501
|
-
}
|
|
502
|
-
throw new Error(`Authentication failed: ${response.statusText}`);
|
|
503
|
-
}
|
|
504
|
-
const user = await response.json();
|
|
505
|
-
return { user, token: authToken };
|
|
506
|
-
} catch (error) {
|
|
507
|
-
console.error("Auth error:", error);
|
|
508
|
-
return { user: null };
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
567
|
async function logout(token) {
|
|
512
568
|
const config = getConfig();
|
|
513
|
-
const authToken = token ||
|
|
569
|
+
const authToken = token || getEnv3("DO_TOKEN") || "";
|
|
514
570
|
if (!authToken) {
|
|
515
571
|
return;
|
|
516
572
|
}
|
|
@@ -529,6 +585,30 @@ async function logout(token) {
|
|
|
529
585
|
console.error("Logout error:", error);
|
|
530
586
|
}
|
|
531
587
|
}
|
|
588
|
+
async function getToken() {
|
|
589
|
+
const adminToken = getEnv3("DO_ADMIN_TOKEN");
|
|
590
|
+
if (adminToken) return adminToken;
|
|
591
|
+
const doToken = getEnv3("DO_TOKEN");
|
|
592
|
+
if (doToken) return doToken;
|
|
593
|
+
try {
|
|
594
|
+
const { env } = await import('cloudflare:workers');
|
|
595
|
+
const cfAdminToken = await resolveSecret(env.DO_ADMIN_TOKEN);
|
|
596
|
+
if (cfAdminToken) return cfAdminToken;
|
|
597
|
+
const cfToken = await resolveSecret(env.DO_TOKEN);
|
|
598
|
+
if (cfToken) return cfToken;
|
|
599
|
+
} catch {
|
|
600
|
+
}
|
|
601
|
+
try {
|
|
602
|
+
const { createSecureStorage: createSecureStorage2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
603
|
+
const storage2 = createSecureStorage2();
|
|
604
|
+
return await storage2.getToken();
|
|
605
|
+
} catch {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function auth() {
|
|
610
|
+
return getToken;
|
|
611
|
+
}
|
|
532
612
|
|
|
533
613
|
// src/cli.ts
|
|
534
614
|
init_storage();
|
|
@@ -616,19 +696,6 @@ function printVersion() {
|
|
|
616
696
|
console.log("oauth.do");
|
|
617
697
|
}
|
|
618
698
|
}
|
|
619
|
-
async function waitForEnter(prompt) {
|
|
620
|
-
const readline = await import('readline');
|
|
621
|
-
const rl = readline.createInterface({
|
|
622
|
-
input: process.stdin,
|
|
623
|
-
output: process.stdout
|
|
624
|
-
});
|
|
625
|
-
return new Promise((resolve) => {
|
|
626
|
-
rl.question(prompt, () => {
|
|
627
|
-
rl.close();
|
|
628
|
-
resolve();
|
|
629
|
-
});
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
699
|
async function loginCommand() {
|
|
633
700
|
try {
|
|
634
701
|
console.log(`${colors.bright}Starting OAuth login...${colors.reset}
|
|
@@ -644,7 +711,6 @@ ${colors.bright}To complete login:${colors.reset}`);
|
|
|
644
711
|
${colors.dim}Or open this URL directly:${colors.reset}`);
|
|
645
712
|
console.log(` ${colors.blue}${authResponse.verification_uri_complete}${colors.reset}
|
|
646
713
|
`);
|
|
647
|
-
await waitForEnter(`${colors.cyan}Press Enter to open browser...${colors.reset}`);
|
|
648
714
|
const open = await import('open').catch(() => null);
|
|
649
715
|
if (open) {
|
|
650
716
|
try {
|
|
@@ -677,12 +743,11 @@ ${colors.dim}Logged in as:${colors.reset}`);
|
|
|
677
743
|
console.log(` ${colors.gray}${authResult.user.email}${colors.reset}`);
|
|
678
744
|
}
|
|
679
745
|
}
|
|
680
|
-
const
|
|
681
|
-
if (typeof
|
|
682
|
-
const storageInfo = await
|
|
683
|
-
const storageLabel = storageInfo.type === "keychain" ? `${colors.green}OS Keychain${colors.reset}` : `${colors.yellow}Secure File${colors.reset}`;
|
|
746
|
+
const fileStorage = storage;
|
|
747
|
+
if (typeof fileStorage.getStorageInfo === "function") {
|
|
748
|
+
const storageInfo = await fileStorage.getStorageInfo();
|
|
684
749
|
console.log(`
|
|
685
|
-
${colors.dim}Token stored in: ${
|
|
750
|
+
${colors.dim}Token stored in: ${colors.green}~/.oauth.do/token${colors.reset}${colors.reset}`);
|
|
686
751
|
}
|
|
687
752
|
} catch (error) {
|
|
688
753
|
printError("Login failed", error instanceof Error ? error : void 0);
|
|
@@ -754,16 +819,11 @@ async function statusCommand() {
|
|
|
754
819
|
try {
|
|
755
820
|
console.log(`${colors.bright}OAuth.do Status${colors.reset}
|
|
756
821
|
`);
|
|
757
|
-
const
|
|
758
|
-
if (typeof
|
|
759
|
-
const storageInfo = await
|
|
760
|
-
|
|
761
|
-
console.log(
|
|
762
|
-
if (storageInfo.type === "keychain") {
|
|
763
|
-
console.log(` ${colors.dim}Using system credential manager (most secure)${colors.reset}`);
|
|
764
|
-
} else {
|
|
765
|
-
console.log(` ${colors.dim}Using ~/.oauth.do/token with 0600 permissions${colors.reset}`);
|
|
766
|
-
}
|
|
822
|
+
const fileStorage = storage;
|
|
823
|
+
if (typeof fileStorage.getStorageInfo === "function") {
|
|
824
|
+
const storageInfo = await fileStorage.getStorageInfo();
|
|
825
|
+
console.log(`${colors.cyan}Storage:${colors.reset} ${colors.green}Secure File${colors.reset}`);
|
|
826
|
+
console.log(` ${colors.dim}Using ~/.oauth.do/token with 0600 permissions${colors.reset}`);
|
|
767
827
|
}
|
|
768
828
|
const token = await storage.getToken();
|
|
769
829
|
if (!token) {
|
|
@@ -791,6 +851,32 @@ Run ${colors.cyan}oauth.do login${colors.reset} to re-authenticate`);
|
|
|
791
851
|
process.exit(1);
|
|
792
852
|
}
|
|
793
853
|
}
|
|
854
|
+
async function autoLoginOrShowUser() {
|
|
855
|
+
try {
|
|
856
|
+
const token = await storage.getToken();
|
|
857
|
+
if (token) {
|
|
858
|
+
const authResult = await auth(token);
|
|
859
|
+
if (authResult.user) {
|
|
860
|
+
console.log(`${colors.green}\u2713${colors.reset} Already authenticated
|
|
861
|
+
`);
|
|
862
|
+
if (authResult.user.name) {
|
|
863
|
+
console.log(` ${colors.bright}${authResult.user.name}${colors.reset}`);
|
|
864
|
+
}
|
|
865
|
+
if (authResult.user.email) {
|
|
866
|
+
console.log(` ${colors.gray}${authResult.user.email}${colors.reset}`);
|
|
867
|
+
}
|
|
868
|
+
if (authResult.user.id) {
|
|
869
|
+
console.log(` ${colors.dim}ID: ${authResult.user.id}${colors.reset}`);
|
|
870
|
+
}
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
printInfo("Session expired, logging in again...\n");
|
|
874
|
+
}
|
|
875
|
+
await loginCommand();
|
|
876
|
+
} catch (error) {
|
|
877
|
+
await loginCommand();
|
|
878
|
+
}
|
|
879
|
+
}
|
|
794
880
|
async function main() {
|
|
795
881
|
configureFromEnv();
|
|
796
882
|
const args = process.argv.slice(2);
|
|
@@ -808,9 +894,11 @@ async function main() {
|
|
|
808
894
|
const command = args.find((arg) => !arg.startsWith("--"));
|
|
809
895
|
switch (command) {
|
|
810
896
|
case "login":
|
|
811
|
-
case void 0:
|
|
812
897
|
await loginCommand();
|
|
813
898
|
break;
|
|
899
|
+
case void 0:
|
|
900
|
+
await autoLoginOrShowUser();
|
|
901
|
+
break;
|
|
814
902
|
case "logout":
|
|
815
903
|
await logoutCommand();
|
|
816
904
|
break;
|