main
1#!/usr/bin/env node
2
3import {
4 CREDENTIALS_PATH,
5 TOKEN_PATH,
6 DEFAULT_SCOPES,
7 authorize,
8 clearToken,
9 credentialsExist,
10 formatScopes,
11 loadToken,
12} from "./common.js";
13
14function printHelp() {
15 console.log(`Google Workspace auth helper
16
17Usage:
18 node auth.js login [--scopes scope1,scope2,...]
19 node auth.js status
20 node auth.js clear
21
22Environment overrides:
23 GOOGLE_WORKSPACE_CONFIG_DIR
24 GOOGLE_WORKSPACE_CREDENTIALS
25 GOOGLE_WORKSPACE_TOKEN
26`);
27}
28
29function parseScopes(args) {
30 const idx = args.indexOf("--scopes");
31 if (idx === -1) {
32 return DEFAULT_SCOPES;
33 }
34 const raw = args[idx + 1];
35 if (!raw) {
36 throw new Error("--scopes requires a value");
37 }
38 const scopes = formatScopes(raw);
39 if (scopes.length === 0) {
40 throw new Error("--scopes produced an empty scope list");
41 }
42 return scopes;
43}
44
45async function doLogin(args) {
46 const scopes = parseScopes(args);
47 await authorize({ scopes, interactive: true });
48 console.log("✅ Login successful. Token stored at:");
49 console.log(` ${TOKEN_PATH}`);
50}
51
52function doStatus() {
53 console.log("Credentials file:");
54 console.log(` ${CREDENTIALS_PATH}`);
55 console.log(` Exists: ${credentialsExist() ? "yes" : "no"}`);
56
57 const token = loadToken();
58
59 console.log("\nToken file:");
60 console.log(` ${TOKEN_PATH}`);
61 console.log(` Exists: ${token ? "yes" : "no"}`);
62
63 if (!token) {
64 return;
65 }
66
67 const now = Date.now();
68 const expiry = token.expiry_date || null;
69 const expired = expiry ? expiry < now : null;
70 const scopeCount = formatScopes(token.scope).length;
71
72 console.log("\nToken details:");
73 console.log(` access_token: ${token.access_token ? "present" : "missing"}`);
74 console.log(
75 ` refresh_token: ${token.refresh_token ? "present" : "missing"}`
76 );
77 console.log(` scopes: ${scopeCount}`);
78
79 if (expiry) {
80 console.log(` expiry_date: ${new Date(expiry).toISOString()}`);
81 console.log(` expired: ${expired ? "yes" : "no"}`);
82 } else {
83 console.log(" expiry_date: n/a");
84 }
85}
86
87function doClear() {
88 clearToken();
89 console.log("✅ Token cleared.");
90}
91
92async function main() {
93 const [command, ...args] = process.argv.slice(2);
94
95 if (
96 !command ||
97 command === "help" ||
98 command === "--help" ||
99 command === "-h"
100 ) {
101 printHelp();
102 return;
103 }
104
105 if (command === "login") {
106 await doLogin(args);
107 return;
108 }
109
110 if (command === "status") {
111 doStatus();
112 return;
113 }
114
115 if (command === "clear") {
116 doClear();
117 return;
118 }
119
120 throw new Error(`Unknown command: ${command}`);
121}
122
123main().catch((error) => {
124 console.error(`❌ ${error.message}`);
125 process.exit(1);
126});