@gpdoc/cli 1.1.0 → 1.2.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/bin/gpdoc.js +11 -1
- package/lib/auth.js +13 -2
- package/package.json +1 -1
package/bin/gpdoc.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @spec CLI-001, CLI-002, CLI-003, CLI-004, CLI-005, CLI-006, CLI-007, CLI-008, CLI-009, CLI-014, CLI-015
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
3
4
|
import { access, readFile, rename, stat, unlink, writeFile } from 'node:fs/promises';
|
|
4
5
|
import { spawn } from 'node:child_process';
|
|
5
6
|
import path from 'node:path';
|
|
@@ -251,7 +252,16 @@ export async function run(argv, runtime = {}) {
|
|
|
251
252
|
else if (warnings.length) process.stderr.write(`${warnings.join('\n')}\n`);
|
|
252
253
|
}
|
|
253
254
|
|
|
254
|
-
|
|
255
|
+
function isCliEntrypoint() {
|
|
256
|
+
if (!process.argv[1]) return false;
|
|
257
|
+
try {
|
|
258
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
|
|
259
|
+
} catch {
|
|
260
|
+
return path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (isCliEntrypoint()) {
|
|
255
265
|
try {
|
|
256
266
|
await run(process.argv.slice(2));
|
|
257
267
|
} catch (error) {
|
package/lib/auth.js
CHANGED
|
@@ -11,7 +11,10 @@ export class AuthError extends Error {
|
|
|
11
11
|
|
|
12
12
|
const DEFAULT_ISSUER = 'https://auth.gpdoc.io/';
|
|
13
13
|
const DEFAULT_AUDIENCE = 'https://gpdoc.us.auth0.com/api/v2/';
|
|
14
|
-
|
|
14
|
+
// This is GPDoc's public native client. Unlike the browser client, it is
|
|
15
|
+
// explicitly approved for Auth0's Device Authorization Grant.
|
|
16
|
+
const DEFAULT_CLIENT_ID = 'hSllIhEMtrPrLtPZpYnNf0MOQbreziL8';
|
|
17
|
+
const DEFAULT_SCOPE = 'openid profile email offline_access';
|
|
15
18
|
|
|
16
19
|
function credentialPath(env) {
|
|
17
20
|
if (env.GPDOC_CREDENTIALS_PATH) return path.resolve(env.GPDOC_CREDENTIALS_PATH);
|
|
@@ -64,6 +67,7 @@ function configuration(env) {
|
|
|
64
67
|
issuer,
|
|
65
68
|
audience: env.GPDOC_AUTH0_AUDIENCE || DEFAULT_AUDIENCE,
|
|
66
69
|
clientId: env.GPDOC_AUTH0_CLIENT_ID || DEFAULT_CLIENT_ID,
|
|
70
|
+
scope: env.GPDOC_AUTH0_SCOPE || DEFAULT_SCOPE,
|
|
67
71
|
deviceAuthorizationEndpoint: new URL('oauth/device/code', issuer).toString(),
|
|
68
72
|
tokenEndpoint: new URL('oauth/token', issuer).toString(),
|
|
69
73
|
};
|
|
@@ -112,9 +116,16 @@ export async function createAuthManager({ env = process.env, fetchImpl = globalT
|
|
|
112
116
|
const { response, payload } = await requestJson(fetchImpl, config.deviceAuthorizationEndpoint, {
|
|
113
117
|
method: 'POST',
|
|
114
118
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
115
|
-
body: new URLSearchParams({
|
|
119
|
+
body: new URLSearchParams({
|
|
120
|
+
client_id: config.clientId,
|
|
121
|
+
audience: config.audience,
|
|
122
|
+
scope: config.scope,
|
|
123
|
+
}),
|
|
116
124
|
});
|
|
117
125
|
if (!response.ok || typeof payload.device_code !== 'string' || typeof payload.user_code !== 'string' || typeof payload.verification_uri !== 'string') {
|
|
126
|
+
if (payload.error === 'unauthorized_client') {
|
|
127
|
+
throw new AuthError('AUTH_DEVICE_FLOW_UNAVAILABLE', 'The configured GPDoc Auth0 client does not support terminal device authorization.');
|
|
128
|
+
}
|
|
118
129
|
throw new AuthError('AUTH_FAILED', 'GPDoc could not start device authorization.');
|
|
119
130
|
}
|
|
120
131
|
const intervalSeconds = Math.max(1, Number(payload.interval || 5));
|