@aaronsb/kg-cli 0.6.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/README.md +112 -0
- package/dist/api/client.d.ts +867 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +1362 -0
- package/dist/api/client.js.map +1 -0
- package/dist/cli/admin/backup.d.ts +9 -0
- package/dist/cli/admin/backup.d.ts.map +1 -0
- package/dist/cli/admin/backup.js +363 -0
- package/dist/cli/admin/backup.js.map +1 -0
- package/dist/cli/admin/index.d.ts +7 -0
- package/dist/cli/admin/index.d.ts.map +1 -0
- package/dist/cli/admin/index.js +52 -0
- package/dist/cli/admin/index.js.map +1 -0
- package/dist/cli/admin/scheduler.d.ts +7 -0
- package/dist/cli/admin/scheduler.d.ts.map +1 -0
- package/dist/cli/admin/scheduler.js +125 -0
- package/dist/cli/admin/scheduler.js.map +1 -0
- package/dist/cli/admin/status.d.ts +7 -0
- package/dist/cli/admin/status.d.ts.map +1 -0
- package/dist/cli/admin/status.js +134 -0
- package/dist/cli/admin/status.js.map +1 -0
- package/dist/cli/admin/utils.d.ts +34 -0
- package/dist/cli/admin/utils.d.ts.map +1 -0
- package/dist/cli/admin/utils.js +441 -0
- package/dist/cli/admin/utils.js.map +1 -0
- package/dist/cli/ai-config/embedding.d.ts +11 -0
- package/dist/cli/ai-config/embedding.d.ts.map +1 -0
- package/dist/cli/ai-config/embedding.js +598 -0
- package/dist/cli/ai-config/embedding.js.map +1 -0
- package/dist/cli/ai-config/extraction.d.ts +11 -0
- package/dist/cli/ai-config/extraction.d.ts.map +1 -0
- package/dist/cli/ai-config/extraction.js +206 -0
- package/dist/cli/ai-config/extraction.js.map +1 -0
- package/dist/cli/ai-config/index.d.ts +21 -0
- package/dist/cli/ai-config/index.d.ts.map +1 -0
- package/dist/cli/ai-config/index.js +27 -0
- package/dist/cli/ai-config/index.js.map +1 -0
- package/dist/cli/ai-config/keys.d.ts +11 -0
- package/dist/cli/ai-config/keys.d.ts.map +1 -0
- package/dist/cli/ai-config/keys.js +182 -0
- package/dist/cli/ai-config/keys.js.map +1 -0
- package/dist/cli/ai-config/utils.d.ts +13 -0
- package/dist/cli/ai-config/utils.d.ts.map +1 -0
- package/dist/cli/ai-config/utils.js +84 -0
- package/dist/cli/ai-config/utils.js.map +1 -0
- package/dist/cli/artifact.d.ts +8 -0
- package/dist/cli/artifact.d.ts.map +1 -0
- package/dist/cli/artifact.js +296 -0
- package/dist/cli/artifact.js.map +1 -0
- package/dist/cli/auth-admin.d.ts +11 -0
- package/dist/cli/auth-admin.d.ts.map +1 -0
- package/dist/cli/auth-admin.js +415 -0
- package/dist/cli/auth-admin.js.map +1 -0
- package/dist/cli/colors.d.ts +105 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +164 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands.d.ts +6 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +164 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +6 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +694 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/curve-viz.d.ts +89 -0
- package/dist/cli/curve-viz.d.ts.map +1 -0
- package/dist/cli/curve-viz.js +228 -0
- package/dist/cli/curve-viz.js.map +1 -0
- package/dist/cli/database.d.ts +6 -0
- package/dist/cli/database.d.ts.map +1 -0
- package/dist/cli/database.js +324 -0
- package/dist/cli/database.js.map +1 -0
- package/dist/cli/document.d.ts +6 -0
- package/dist/cli/document.d.ts.map +1 -0
- package/dist/cli/document.js +458 -0
- package/dist/cli/document.js.map +1 -0
- package/dist/cli/group.d.ts +8 -0
- package/dist/cli/group.d.ts.map +1 -0
- package/dist/cli/group.js +174 -0
- package/dist/cli/group.js.map +1 -0
- package/dist/cli/health.d.ts +6 -0
- package/dist/cli/health.d.ts.map +1 -0
- package/dist/cli/health.js +34 -0
- package/dist/cli/health.js.map +1 -0
- package/dist/cli/help-formatter.d.ts +16 -0
- package/dist/cli/help-formatter.d.ts.map +1 -0
- package/dist/cli/help-formatter.js +248 -0
- package/dist/cli/help-formatter.js.map +1 -0
- package/dist/cli/help.d.ts +9 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +227 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/ingest.d.ts +6 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +722 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/jobs.d.ts +6 -0
- package/dist/cli/jobs.d.ts.map +1 -0
- package/dist/cli/jobs.js +663 -0
- package/dist/cli/jobs.js.map +1 -0
- package/dist/cli/login.d.ts +21 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +221 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logout.d.ts +16 -0
- package/dist/cli/logout.d.ts.map +1 -0
- package/dist/cli/logout.js +141 -0
- package/dist/cli/logout.js.map +1 -0
- package/dist/cli/mcp-config.d.ts +10 -0
- package/dist/cli/mcp-config.d.ts.map +1 -0
- package/dist/cli/mcp-config.js +358 -0
- package/dist/cli/mcp-config.js.map +1 -0
- package/dist/cli/oauth.d.ts +15 -0
- package/dist/cli/oauth.d.ts.map +1 -0
- package/dist/cli/oauth.js +296 -0
- package/dist/cli/oauth.js.map +1 -0
- package/dist/cli/ontology.d.ts +6 -0
- package/dist/cli/ontology.d.ts.map +1 -0
- package/dist/cli/ontology.js +231 -0
- package/dist/cli/ontology.js.map +1 -0
- package/dist/cli/polarity.d.ts +6 -0
- package/dist/cli/polarity.d.ts.map +1 -0
- package/dist/cli/polarity.js +295 -0
- package/dist/cli/polarity.js.map +1 -0
- package/dist/cli/projection.d.ts +8 -0
- package/dist/cli/projection.d.ts.map +1 -0
- package/dist/cli/projection.js +297 -0
- package/dist/cli/projection.js.map +1 -0
- package/dist/cli/query-def.d.ts +8 -0
- package/dist/cli/query-def.d.ts.map +1 -0
- package/dist/cli/query-def.js +163 -0
- package/dist/cli/query-def.js.map +1 -0
- package/dist/cli/rbac.d.ts +12 -0
- package/dist/cli/rbac.d.ts.map +1 -0
- package/dist/cli/rbac.js +615 -0
- package/dist/cli/rbac.js.map +1 -0
- package/dist/cli/search.d.ts +6 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +829 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/source.d.ts +6 -0
- package/dist/cli/source.d.ts.map +1 -0
- package/dist/cli/source.js +202 -0
- package/dist/cli/source.js.map +1 -0
- package/dist/cli/verb-router.d.ts +25 -0
- package/dist/cli/verb-router.d.ts.map +1 -0
- package/dist/cli/verb-router.js +415 -0
- package/dist/cli/verb-router.js.map +1 -0
- package/dist/cli/vocabulary/config.d.ts +7 -0
- package/dist/cli/vocabulary/config.d.ts.map +1 -0
- package/dist/cli/vocabulary/config.js +201 -0
- package/dist/cli/vocabulary/config.js.map +1 -0
- package/dist/cli/vocabulary/consolidate.d.ts +8 -0
- package/dist/cli/vocabulary/consolidate.d.ts.map +1 -0
- package/dist/cli/vocabulary/consolidate.js +192 -0
- package/dist/cli/vocabulary/consolidate.js.map +1 -0
- package/dist/cli/vocabulary/embeddings.d.ts +9 -0
- package/dist/cli/vocabulary/embeddings.d.ts.map +1 -0
- package/dist/cli/vocabulary/embeddings.js +205 -0
- package/dist/cli/vocabulary/embeddings.js.map +1 -0
- package/dist/cli/vocabulary/epistemic.d.ts +7 -0
- package/dist/cli/vocabulary/epistemic.d.ts.map +1 -0
- package/dist/cli/vocabulary/epistemic.js +315 -0
- package/dist/cli/vocabulary/epistemic.js.map +1 -0
- package/dist/cli/vocabulary/index.d.ts +7 -0
- package/dist/cli/vocabulary/index.d.ts.map +1 -0
- package/dist/cli/vocabulary/index.js +45 -0
- package/dist/cli/vocabulary/index.js.map +1 -0
- package/dist/cli/vocabulary/profiles.d.ts +7 -0
- package/dist/cli/vocabulary/profiles.d.ts.map +1 -0
- package/dist/cli/vocabulary/profiles.js +171 -0
- package/dist/cli/vocabulary/profiles.js.map +1 -0
- package/dist/cli/vocabulary/similarity.d.ts +9 -0
- package/dist/cli/vocabulary/similarity.d.ts.map +1 -0
- package/dist/cli/vocabulary/similarity.js +199 -0
- package/dist/cli/vocabulary/similarity.js.map +1 -0
- package/dist/cli/vocabulary/status.d.ts +8 -0
- package/dist/cli/vocabulary/status.d.ts.map +1 -0
- package/dist/cli/vocabulary/status.js +280 -0
- package/dist/cli/vocabulary/status.js.map +1 -0
- package/dist/cli/vocabulary/sync.d.ts +7 -0
- package/dist/cli/vocabulary/sync.d.ts.map +1 -0
- package/dist/cli/vocabulary/sync.js +111 -0
- package/dist/cli/vocabulary/sync.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth/auth-client.d.ts +247 -0
- package/dist/lib/auth/auth-client.d.ts.map +1 -0
- package/dist/lib/auth/auth-client.js +305 -0
- package/dist/lib/auth/auth-client.js.map +1 -0
- package/dist/lib/auth/challenge.d.ts +39 -0
- package/dist/lib/auth/challenge.d.ts.map +1 -0
- package/dist/lib/auth/challenge.js +125 -0
- package/dist/lib/auth/challenge.js.map +1 -0
- package/dist/lib/auth/client-credentials-flow.d.ts +58 -0
- package/dist/lib/auth/client-credentials-flow.d.ts.map +1 -0
- package/dist/lib/auth/client-credentials-flow.js +118 -0
- package/dist/lib/auth/client-credentials-flow.js.map +1 -0
- package/dist/lib/auth/device-flow.d.ts +75 -0
- package/dist/lib/auth/device-flow.d.ts.map +1 -0
- package/dist/lib/auth/device-flow.js +177 -0
- package/dist/lib/auth/device-flow.js.map +1 -0
- package/dist/lib/auth/index.d.ts +14 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +34 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/oauth-types.d.ts +69 -0
- package/dist/lib/auth/oauth-types.d.ts.map +1 -0
- package/dist/lib/auth/oauth-types.js +10 -0
- package/dist/lib/auth/oauth-types.js.map +1 -0
- package/dist/lib/auth/oauth-utils.d.ts +51 -0
- package/dist/lib/auth/oauth-utils.d.ts.map +1 -0
- package/dist/lib/auth/oauth-utils.js +110 -0
- package/dist/lib/auth/oauth-utils.js.map +1 -0
- package/dist/lib/auth/token-manager.d.ts +87 -0
- package/dist/lib/auth/token-manager.d.ts.map +1 -0
- package/dist/lib/auth/token-manager.js +139 -0
- package/dist/lib/auth/token-manager.js.map +1 -0
- package/dist/lib/auth/token-refresh.d.ts +63 -0
- package/dist/lib/auth/token-refresh.d.ts.map +1 -0
- package/dist/lib/auth/token-refresh.js +141 -0
- package/dist/lib/auth/token-refresh.js.map +1 -0
- package/dist/lib/config.d.ts +286 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +537 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/job-stream.d.ts +53 -0
- package/dist/lib/job-stream.d.ts.map +1 -0
- package/dist/lib/job-stream.js +153 -0
- package/dist/lib/job-stream.js.map +1 -0
- package/dist/lib/mcp-allowlist.d.ts +101 -0
- package/dist/lib/mcp-allowlist.d.ts.map +1 -0
- package/dist/lib/mcp-allowlist.js +340 -0
- package/dist/lib/mcp-allowlist.js.map +1 -0
- package/dist/lib/table-example.d.ts +7 -0
- package/dist/lib/table-example.d.ts.map +1 -0
- package/dist/lib/table-example.js +105 -0
- package/dist/lib/table-example.js.map +1 -0
- package/dist/lib/table.d.ts +95 -0
- package/dist/lib/table.d.ts.map +1 -0
- package/dist/lib/table.js +263 -0
- package/dist/lib/table.js.map +1 -0
- package/dist/lib/terminal-images.d.ts +66 -0
- package/dist/lib/terminal-images.d.ts.map +1 -0
- package/dist/lib/terminal-images.js +268 -0
- package/dist/lib/terminal-images.js.map +1 -0
- package/dist/mcp/formatters.d.ts +100 -0
- package/dist/mcp/formatters.d.ts.map +1 -0
- package/dist/mcp/formatters.js +1411 -0
- package/dist/mcp/formatters.js.map +1 -0
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1810 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/types/index.d.ts +742 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Device Authorization Grant Flow (ADR-054)
|
|
3
|
+
*
|
|
4
|
+
* Implements RFC 8628 Device Authorization Grant for CLI authentication.
|
|
5
|
+
*
|
|
6
|
+
* Flow:
|
|
7
|
+
* 1. Request device and user codes from server
|
|
8
|
+
* 2. Display user_code to user with verification URL
|
|
9
|
+
* 3. Poll token endpoint until user authorizes (or timeout/denial)
|
|
10
|
+
* 4. Store access and refresh tokens
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const flow = new DeviceAuthFlow(apiUrl, clientId);
|
|
14
|
+
* const codes = await flow.requestDeviceCode();
|
|
15
|
+
* console.log(`Go to ${codes.verification_uri} and enter: ${codes.user_code}`);
|
|
16
|
+
* const tokens = await flow.pollForToken(codes.device_code, codes.interval);
|
|
17
|
+
*/
|
|
18
|
+
import type { DeviceAuthorizationResponse, OAuthTokenInfo } from './oauth-types';
|
|
19
|
+
export interface DeviceFlowCallbacks {
|
|
20
|
+
onDeviceCodeReceived?: (codes: DeviceAuthorizationResponse) => void;
|
|
21
|
+
onPollStart?: () => void;
|
|
22
|
+
onPollTick?: (attempt: number) => void;
|
|
23
|
+
onAuthorizationPending?: () => void;
|
|
24
|
+
onSlowDown?: () => void;
|
|
25
|
+
onSuccess?: (tokenInfo: OAuthTokenInfo) => void;
|
|
26
|
+
onError?: (error: Error) => void;
|
|
27
|
+
}
|
|
28
|
+
export declare class DeviceAuthFlow {
|
|
29
|
+
private client;
|
|
30
|
+
private clientId;
|
|
31
|
+
constructor(apiUrl: string, clientId?: string);
|
|
32
|
+
/**
|
|
33
|
+
* Step 1: Request device and user codes from the authorization server
|
|
34
|
+
*
|
|
35
|
+
* POST /auth/oauth/device
|
|
36
|
+
* Body: client_id=kg-cli&scope=read:* write:*
|
|
37
|
+
*
|
|
38
|
+
* Returns codes and verification URL for the user
|
|
39
|
+
*/
|
|
40
|
+
requestDeviceCode(scope?: string): Promise<DeviceAuthorizationResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Step 2: Poll token endpoint until user authorizes
|
|
43
|
+
*
|
|
44
|
+
* POST /auth/oauth/token
|
|
45
|
+
* Body: grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=<code>&client_id=kg-cli
|
|
46
|
+
*
|
|
47
|
+
* Polls every `interval` seconds until:
|
|
48
|
+
* - User authorizes (returns tokens)
|
|
49
|
+
* - User denies (throws error)
|
|
50
|
+
* - Device code expires (throws error)
|
|
51
|
+
* - Timeout reached (throws error)
|
|
52
|
+
*
|
|
53
|
+
* @param deviceCode - Device code from requestDeviceCode()
|
|
54
|
+
* @param interval - Polling interval in seconds (from requestDeviceCode())
|
|
55
|
+
* @param maxAttempts - Maximum number of poll attempts (default: 120 = 10 minutes at 5s interval)
|
|
56
|
+
* @param callbacks - Optional callbacks for progress tracking
|
|
57
|
+
* @returns OAuth token information
|
|
58
|
+
*/
|
|
59
|
+
pollForToken(deviceCode: string, interval?: number, maxAttempts?: number, callbacks?: DeviceFlowCallbacks): Promise<OAuthTokenInfo>;
|
|
60
|
+
/**
|
|
61
|
+
* Complete device flow: request codes and poll for token
|
|
62
|
+
*
|
|
63
|
+
* Convenience method that combines requestDeviceCode() and pollForToken()
|
|
64
|
+
*
|
|
65
|
+
* @param scope - OAuth scopes to request
|
|
66
|
+
* @param callbacks - Optional callbacks for progress tracking
|
|
67
|
+
* @returns OAuth token information
|
|
68
|
+
*/
|
|
69
|
+
authenticate(scope?: string, callbacks?: DeviceFlowCallbacks): Promise<OAuthTokenInfo>;
|
|
70
|
+
/**
|
|
71
|
+
* Sleep utility for polling
|
|
72
|
+
*/
|
|
73
|
+
private sleep;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=device-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EACV,2BAA2B,EAE3B,cAAc,EAEf,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,mBAAmB;IAClC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;IACpE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAiB;IAWvD;;;;;;;OAOG;IACG,iBAAiB,CAAC,KAAK,GAAE,MAAyB,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAyB/F;;;;;;;;;;;;;;;;;OAiBG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAU,EACpB,WAAW,GAAE,MAAY,EACzB,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,cAAc,CAAC;IA+E1B;;;;;;;;OAQG;IACG,YAAY,CAAC,KAAK,GAAE,MAAyB,EAAE,SAAS,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAS9G;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth Device Authorization Grant Flow (ADR-054)
|
|
4
|
+
*
|
|
5
|
+
* Implements RFC 8628 Device Authorization Grant for CLI authentication.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Request device and user codes from server
|
|
9
|
+
* 2. Display user_code to user with verification URL
|
|
10
|
+
* 3. Poll token endpoint until user authorizes (or timeout/denial)
|
|
11
|
+
* 4. Store access and refresh tokens
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* const flow = new DeviceAuthFlow(apiUrl, clientId);
|
|
15
|
+
* const codes = await flow.requestDeviceCode();
|
|
16
|
+
* console.log(`Go to ${codes.verification_uri} and enter: ${codes.user_code}`);
|
|
17
|
+
* const tokens = await flow.pollForToken(codes.device_code, codes.interval);
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.DeviceAuthFlow = void 0;
|
|
24
|
+
const axios_1 = __importDefault(require("axios"));
|
|
25
|
+
const oauth_utils_1 = require("./oauth-utils");
|
|
26
|
+
class DeviceAuthFlow {
|
|
27
|
+
constructor(apiUrl, clientId = 'kg-cli') {
|
|
28
|
+
this.clientId = clientId;
|
|
29
|
+
this.client = axios_1.default.create({
|
|
30
|
+
baseURL: apiUrl,
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
33
|
+
},
|
|
34
|
+
timeout: 10000, // 10 seconds for API calls
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Step 1: Request device and user codes from the authorization server
|
|
39
|
+
*
|
|
40
|
+
* POST /auth/oauth/device
|
|
41
|
+
* Body: client_id=kg-cli&scope=read:* write:*
|
|
42
|
+
*
|
|
43
|
+
* Returns codes and verification URL for the user
|
|
44
|
+
*/
|
|
45
|
+
async requestDeviceCode(scope = 'read:* write:*') {
|
|
46
|
+
try {
|
|
47
|
+
const params = new URLSearchParams({
|
|
48
|
+
client_id: this.clientId,
|
|
49
|
+
scope: scope,
|
|
50
|
+
});
|
|
51
|
+
const response = await this.client.post('/auth/oauth/device', params.toString());
|
|
52
|
+
return response.data;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
56
|
+
const axiosError = error;
|
|
57
|
+
const errorMessage = axiosError.response?.data?.error_description ||
|
|
58
|
+
axiosError.response?.data?.error ||
|
|
59
|
+
axiosError.message;
|
|
60
|
+
throw new Error(`Failed to request device code: ${errorMessage}`);
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Step 2: Poll token endpoint until user authorizes
|
|
67
|
+
*
|
|
68
|
+
* POST /auth/oauth/token
|
|
69
|
+
* Body: grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=<code>&client_id=kg-cli
|
|
70
|
+
*
|
|
71
|
+
* Polls every `interval` seconds until:
|
|
72
|
+
* - User authorizes (returns tokens)
|
|
73
|
+
* - User denies (throws error)
|
|
74
|
+
* - Device code expires (throws error)
|
|
75
|
+
* - Timeout reached (throws error)
|
|
76
|
+
*
|
|
77
|
+
* @param deviceCode - Device code from requestDeviceCode()
|
|
78
|
+
* @param interval - Polling interval in seconds (from requestDeviceCode())
|
|
79
|
+
* @param maxAttempts - Maximum number of poll attempts (default: 120 = 10 minutes at 5s interval)
|
|
80
|
+
* @param callbacks - Optional callbacks for progress tracking
|
|
81
|
+
* @returns OAuth token information
|
|
82
|
+
*/
|
|
83
|
+
async pollForToken(deviceCode, interval = 5, maxAttempts = 120, callbacks) {
|
|
84
|
+
callbacks?.onPollStart?.();
|
|
85
|
+
let attempt = 0;
|
|
86
|
+
let currentInterval = interval * 1000; // Convert to milliseconds
|
|
87
|
+
while (attempt < maxAttempts) {
|
|
88
|
+
attempt++;
|
|
89
|
+
callbacks?.onPollTick?.(attempt);
|
|
90
|
+
try {
|
|
91
|
+
// Wait before polling (except first attempt)
|
|
92
|
+
if (attempt > 1) {
|
|
93
|
+
await this.sleep(currentInterval);
|
|
94
|
+
}
|
|
95
|
+
const params = new URLSearchParams({
|
|
96
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
97
|
+
device_code: deviceCode,
|
|
98
|
+
client_id: this.clientId,
|
|
99
|
+
});
|
|
100
|
+
const response = await this.client.post('/auth/oauth/token', params.toString());
|
|
101
|
+
// Success! User authorized
|
|
102
|
+
const tokenInfo = (0, oauth_utils_1.convertTokenResponse)(response.data, this.clientId);
|
|
103
|
+
callbacks?.onSuccess?.(tokenInfo);
|
|
104
|
+
return tokenInfo;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
108
|
+
const axiosError = error;
|
|
109
|
+
const errorCode = axiosError.response?.data?.error;
|
|
110
|
+
const errorDescription = axiosError.response?.data?.error_description;
|
|
111
|
+
// Handle OAuth error responses
|
|
112
|
+
if (errorCode === 'authorization_pending') {
|
|
113
|
+
// User hasn't completed authorization yet - continue polling
|
|
114
|
+
callbacks?.onAuthorizationPending?.();
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
else if (errorCode === 'slow_down') {
|
|
118
|
+
// Server requested slower polling - increase interval by 5 seconds
|
|
119
|
+
currentInterval += 5000;
|
|
120
|
+
callbacks?.onSlowDown?.();
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
else if (errorCode === 'access_denied') {
|
|
124
|
+
// User explicitly denied authorization
|
|
125
|
+
const err = new Error('User denied authorization');
|
|
126
|
+
callbacks?.onError?.(err);
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
else if (errorCode === 'expired_token' || errorDescription?.includes('expired')) {
|
|
130
|
+
// Device code expired
|
|
131
|
+
const err = new Error('Device code expired. Please try again.');
|
|
132
|
+
callbacks?.onError?.(err);
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// Other OAuth error
|
|
137
|
+
const err = new Error(`OAuth error: ${errorDescription || errorCode || axiosError.message}`);
|
|
138
|
+
callbacks?.onError?.(err);
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Non-axios error
|
|
143
|
+
const err = error instanceof Error ? error : new Error('Unknown error during polling');
|
|
144
|
+
callbacks?.onError?.(err);
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Max attempts reached
|
|
149
|
+
const err = new Error('Polling timeout: User did not authorize within the expected time');
|
|
150
|
+
callbacks?.onError?.(err);
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Complete device flow: request codes and poll for token
|
|
155
|
+
*
|
|
156
|
+
* Convenience method that combines requestDeviceCode() and pollForToken()
|
|
157
|
+
*
|
|
158
|
+
* @param scope - OAuth scopes to request
|
|
159
|
+
* @param callbacks - Optional callbacks for progress tracking
|
|
160
|
+
* @returns OAuth token information
|
|
161
|
+
*/
|
|
162
|
+
async authenticate(scope = 'read:* write:*', callbacks) {
|
|
163
|
+
// Step 1: Get device and user codes
|
|
164
|
+
const codes = await this.requestDeviceCode(scope);
|
|
165
|
+
callbacks?.onDeviceCodeReceived?.(codes);
|
|
166
|
+
// Step 2: Poll for token
|
|
167
|
+
return await this.pollForToken(codes.device_code, codes.interval, undefined, callbacks);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Sleep utility for polling
|
|
171
|
+
*/
|
|
172
|
+
sleep(ms) {
|
|
173
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.DeviceAuthFlow = DeviceAuthFlow;
|
|
177
|
+
//# sourceMappingURL=device-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Authentication Library (ADR-054)
|
|
3
|
+
*
|
|
4
|
+
* Exports all OAuth utilities for CLI and MCP authentication
|
|
5
|
+
*/
|
|
6
|
+
export * from './oauth-types';
|
|
7
|
+
export * from './oauth-utils';
|
|
8
|
+
export * from './device-flow';
|
|
9
|
+
export * from './client-credentials-flow';
|
|
10
|
+
export * from './token-refresh';
|
|
11
|
+
export * from './auth-client';
|
|
12
|
+
export * from './challenge';
|
|
13
|
+
export * from './token-manager';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAGhC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth 2.0 Authentication Library (ADR-054)
|
|
4
|
+
*
|
|
5
|
+
* Exports all OAuth utilities for CLI and MCP authentication
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
// Types
|
|
23
|
+
__exportStar(require("./oauth-types"), exports);
|
|
24
|
+
// Utilities
|
|
25
|
+
__exportStar(require("./oauth-utils"), exports);
|
|
26
|
+
// Flow implementations
|
|
27
|
+
__exportStar(require("./device-flow"), exports);
|
|
28
|
+
__exportStar(require("./client-credentials-flow"), exports);
|
|
29
|
+
__exportStar(require("./token-refresh"), exports);
|
|
30
|
+
// Legacy exports (keeping for backward compatibility during migration)
|
|
31
|
+
__exportStar(require("./auth-client"), exports);
|
|
32
|
+
__exportStar(require("./challenge"), exports);
|
|
33
|
+
__exportStar(require("./token-manager"), exports);
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,gDAA8B;AAE9B,YAAY;AACZ,gDAA8B;AAE9B,uBAAuB;AACvB,gDAA8B;AAC9B,4DAA0C;AAC1C,kDAAgC;AAEhC,uEAAuE;AACvE,gDAA8B;AAC9B,8CAA4B;AAC5B,kDAAgC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Type Definitions (ADR-054)
|
|
3
|
+
*
|
|
4
|
+
* Shared types for OAuth client flows:
|
|
5
|
+
* - Device Authorization Grant (CLI)
|
|
6
|
+
* - Client Credentials (MCP)
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* OAuth token response from token endpoint
|
|
10
|
+
*/
|
|
11
|
+
export interface OAuthTokenResponse {
|
|
12
|
+
access_token: string;
|
|
13
|
+
token_type: string;
|
|
14
|
+
expires_in: number;
|
|
15
|
+
refresh_token?: string;
|
|
16
|
+
scope: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Device authorization response (RFC 8628)
|
|
20
|
+
*/
|
|
21
|
+
export interface DeviceAuthorizationResponse {
|
|
22
|
+
device_code: string;
|
|
23
|
+
user_code: string;
|
|
24
|
+
verification_uri: string;
|
|
25
|
+
verification_uri_complete?: string;
|
|
26
|
+
expires_in: number;
|
|
27
|
+
interval: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Device code status
|
|
31
|
+
*/
|
|
32
|
+
export interface DeviceCodeStatus {
|
|
33
|
+
status: 'pending' | 'authorized' | 'denied' | 'expired';
|
|
34
|
+
user_code: string;
|
|
35
|
+
expires_at: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* OAuth error response (RFC 6749)
|
|
39
|
+
*/
|
|
40
|
+
export interface OAuthErrorResponse {
|
|
41
|
+
error: string;
|
|
42
|
+
error_description?: string;
|
|
43
|
+
error_uri?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Stored OAuth token information
|
|
47
|
+
*/
|
|
48
|
+
export interface OAuthTokenInfo {
|
|
49
|
+
access_token: string;
|
|
50
|
+
token_type: string;
|
|
51
|
+
expires_at: number;
|
|
52
|
+
refresh_token?: string;
|
|
53
|
+
scope: string;
|
|
54
|
+
client_id: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* OAuth grant types
|
|
58
|
+
*/
|
|
59
|
+
export type OAuthGrantType = 'authorization_code' | 'urn:ietf:params:oauth:grant-type:device_code' | 'client_credentials' | 'refresh_token';
|
|
60
|
+
/**
|
|
61
|
+
* OAuth client configuration
|
|
62
|
+
*/
|
|
63
|
+
export interface OAuthClientConfig {
|
|
64
|
+
client_id: string;
|
|
65
|
+
client_secret?: string;
|
|
66
|
+
grant_types: OAuthGrantType[];
|
|
67
|
+
api_url: string;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=oauth-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-types.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oauth-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,8CAA8C,GAC9C,oBAAoB,GACpB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth 2.0 Type Definitions (ADR-054)
|
|
4
|
+
*
|
|
5
|
+
* Shared types for OAuth client flows:
|
|
6
|
+
* - Device Authorization Grant (CLI)
|
|
7
|
+
* - Client Credentials (MCP)
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=oauth-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-types.js","sourceRoot":"","sources":["../../../src/lib/auth/oauth-types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Utility Functions (ADR-054)
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for OAuth token management
|
|
5
|
+
*/
|
|
6
|
+
import { OAuthTokenInfo, OAuthTokenResponse } from './oauth-types';
|
|
7
|
+
/**
|
|
8
|
+
* Check if an OAuth token is expired or about to expire
|
|
9
|
+
*
|
|
10
|
+
* @param tokenInfo - Token information with expires_at timestamp
|
|
11
|
+
* @param bufferSeconds - How many seconds before expiry to consider token expired (default: 60)
|
|
12
|
+
* @returns true if token is expired or will expire within buffer period
|
|
13
|
+
*/
|
|
14
|
+
export declare function isTokenExpired(tokenInfo: OAuthTokenInfo | null, bufferSeconds?: number): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Convert OAuth token response to storable token info
|
|
17
|
+
*
|
|
18
|
+
* @param response - Token response from API
|
|
19
|
+
* @param clientId - OAuth client ID
|
|
20
|
+
* @returns Token info object ready for storage
|
|
21
|
+
*/
|
|
22
|
+
export declare function convertTokenResponse(response: OAuthTokenResponse, clientId: string): OAuthTokenInfo;
|
|
23
|
+
/**
|
|
24
|
+
* Get time until token expires
|
|
25
|
+
*
|
|
26
|
+
* @param tokenInfo - Token information
|
|
27
|
+
* @returns Seconds until expiration, or 0 if already expired
|
|
28
|
+
*/
|
|
29
|
+
export declare function getTimeUntilExpiry(tokenInfo: OAuthTokenInfo | null): number;
|
|
30
|
+
/**
|
|
31
|
+
* Format expiry time as human-readable string
|
|
32
|
+
*
|
|
33
|
+
* @param tokenInfo - Token information
|
|
34
|
+
* @returns Human-readable expiry time (e.g., "in 45 minutes")
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatExpiryTime(tokenInfo: OAuthTokenInfo | null): string;
|
|
37
|
+
/**
|
|
38
|
+
* Parse scope string into array
|
|
39
|
+
*
|
|
40
|
+
* @param scope - Space-separated scope string
|
|
41
|
+
* @returns Array of individual scopes
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseScopes(scope: string): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Format scope array as space-separated string
|
|
46
|
+
*
|
|
47
|
+
* @param scopes - Array of scopes
|
|
48
|
+
* @returns Space-separated scope string
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatScopes(scopes: string[]): string;
|
|
51
|
+
//# sourceMappingURL=oauth-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oauth-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,aAAa,GAAE,MAAW,GAAG,OAAO,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAWnG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CAS3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CA2BzE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth 2.0 Utility Functions (ADR-054)
|
|
4
|
+
*
|
|
5
|
+
* Shared utilities for OAuth token management
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.isTokenExpired = isTokenExpired;
|
|
9
|
+
exports.convertTokenResponse = convertTokenResponse;
|
|
10
|
+
exports.getTimeUntilExpiry = getTimeUntilExpiry;
|
|
11
|
+
exports.formatExpiryTime = formatExpiryTime;
|
|
12
|
+
exports.parseScopes = parseScopes;
|
|
13
|
+
exports.formatScopes = formatScopes;
|
|
14
|
+
/**
|
|
15
|
+
* Check if an OAuth token is expired or about to expire
|
|
16
|
+
*
|
|
17
|
+
* @param tokenInfo - Token information with expires_at timestamp
|
|
18
|
+
* @param bufferSeconds - How many seconds before expiry to consider token expired (default: 60)
|
|
19
|
+
* @returns true if token is expired or will expire within buffer period
|
|
20
|
+
*/
|
|
21
|
+
function isTokenExpired(tokenInfo, bufferSeconds = 60) {
|
|
22
|
+
if (!tokenInfo) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const now = Math.floor(Date.now() / 1000); // Current time in seconds
|
|
26
|
+
const expiresWithBuffer = tokenInfo.expires_at - bufferSeconds;
|
|
27
|
+
return now >= expiresWithBuffer;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convert OAuth token response to storable token info
|
|
31
|
+
*
|
|
32
|
+
* @param response - Token response from API
|
|
33
|
+
* @param clientId - OAuth client ID
|
|
34
|
+
* @returns Token info object ready for storage
|
|
35
|
+
*/
|
|
36
|
+
function convertTokenResponse(response, clientId) {
|
|
37
|
+
const now = Math.floor(Date.now() / 1000);
|
|
38
|
+
return {
|
|
39
|
+
access_token: response.access_token,
|
|
40
|
+
token_type: response.token_type,
|
|
41
|
+
expires_at: now + response.expires_in,
|
|
42
|
+
refresh_token: response.refresh_token,
|
|
43
|
+
scope: response.scope,
|
|
44
|
+
client_id: clientId,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get time until token expires
|
|
49
|
+
*
|
|
50
|
+
* @param tokenInfo - Token information
|
|
51
|
+
* @returns Seconds until expiration, or 0 if already expired
|
|
52
|
+
*/
|
|
53
|
+
function getTimeUntilExpiry(tokenInfo) {
|
|
54
|
+
if (!tokenInfo) {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
const now = Math.floor(Date.now() / 1000);
|
|
58
|
+
const remaining = tokenInfo.expires_at - now;
|
|
59
|
+
return Math.max(0, remaining);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Format expiry time as human-readable string
|
|
63
|
+
*
|
|
64
|
+
* @param tokenInfo - Token information
|
|
65
|
+
* @returns Human-readable expiry time (e.g., "in 45 minutes")
|
|
66
|
+
*/
|
|
67
|
+
function formatExpiryTime(tokenInfo) {
|
|
68
|
+
if (!tokenInfo) {
|
|
69
|
+
return 'expired';
|
|
70
|
+
}
|
|
71
|
+
const seconds = getTimeUntilExpiry(tokenInfo);
|
|
72
|
+
if (seconds === 0) {
|
|
73
|
+
return 'expired';
|
|
74
|
+
}
|
|
75
|
+
if (seconds < 60) {
|
|
76
|
+
return `in ${seconds} second${seconds !== 1 ? 's' : ''}`;
|
|
77
|
+
}
|
|
78
|
+
const minutes = Math.floor(seconds / 60);
|
|
79
|
+
if (minutes < 60) {
|
|
80
|
+
return `in ${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
|
81
|
+
}
|
|
82
|
+
const hours = Math.floor(minutes / 60);
|
|
83
|
+
if (hours < 24) {
|
|
84
|
+
return `in ${hours} hour${hours !== 1 ? 's' : ''}`;
|
|
85
|
+
}
|
|
86
|
+
const days = Math.floor(hours / 24);
|
|
87
|
+
return `in ${days} day${days !== 1 ? 's' : ''}`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse scope string into array
|
|
91
|
+
*
|
|
92
|
+
* @param scope - Space-separated scope string
|
|
93
|
+
* @returns Array of individual scopes
|
|
94
|
+
*/
|
|
95
|
+
function parseScopes(scope) {
|
|
96
|
+
if (!scope) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return scope.trim().split(/\s+/);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Format scope array as space-separated string
|
|
103
|
+
*
|
|
104
|
+
* @param scopes - Array of scopes
|
|
105
|
+
* @returns Space-separated scope string
|
|
106
|
+
*/
|
|
107
|
+
function formatScopes(scopes) {
|
|
108
|
+
return scopes.join(' ');
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=oauth-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-utils.js","sourceRoot":"","sources":["../../../src/lib/auth/oauth-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages JWT token lifecycle: storage, retrieval, validation, expiration.
|
|
5
|
+
* Tokens are stored in the user's config file (~/.config/kg/config.json).
|
|
6
|
+
*/
|
|
7
|
+
import { ConfigManager } from '../config.js';
|
|
8
|
+
export interface TokenInfo {
|
|
9
|
+
access_token: string;
|
|
10
|
+
token_type: string;
|
|
11
|
+
expires_at: number;
|
|
12
|
+
username: string;
|
|
13
|
+
role: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class TokenManager {
|
|
16
|
+
private config;
|
|
17
|
+
constructor(config: ConfigManager);
|
|
18
|
+
/**
|
|
19
|
+
* Store JWT token with metadata
|
|
20
|
+
*
|
|
21
|
+
* @param tokenInfo Token information including access token, expiration, user details
|
|
22
|
+
*/
|
|
23
|
+
storeToken(tokenInfo: TokenInfo): void;
|
|
24
|
+
/**
|
|
25
|
+
* Retrieve stored token (returns null if expired or not found)
|
|
26
|
+
*
|
|
27
|
+
* @returns Token information or null if not authenticated
|
|
28
|
+
*/
|
|
29
|
+
getToken(): TokenInfo | null;
|
|
30
|
+
/**
|
|
31
|
+
* Check if token is expired (with 5-minute buffer for safety)
|
|
32
|
+
*
|
|
33
|
+
* @param tokenInfo Token information to check
|
|
34
|
+
* @returns true if token is expired or will expire within 5 minutes
|
|
35
|
+
*/
|
|
36
|
+
isTokenExpired(tokenInfo: TokenInfo): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Clear stored token (logout)
|
|
39
|
+
*/
|
|
40
|
+
clearToken(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Check if user is logged in (valid token exists)
|
|
43
|
+
*
|
|
44
|
+
* @returns true if user has a valid, non-expired token
|
|
45
|
+
*/
|
|
46
|
+
isLoggedIn(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Get current username from token
|
|
49
|
+
*
|
|
50
|
+
* @returns Username or null if not logged in
|
|
51
|
+
*/
|
|
52
|
+
getUsername(): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Get current user role from token
|
|
55
|
+
*
|
|
56
|
+
* @returns User role or null if not logged in
|
|
57
|
+
*/
|
|
58
|
+
getRole(): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Get token expiration time as a human-readable string
|
|
61
|
+
*
|
|
62
|
+
* @returns Formatted expiration time or null if not logged in
|
|
63
|
+
*/
|
|
64
|
+
getExpirationString(): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Get minutes until token expiration
|
|
67
|
+
*
|
|
68
|
+
* @returns Minutes until expiration or null if not logged in
|
|
69
|
+
*/
|
|
70
|
+
getMinutesUntilExpiration(): number | null;
|
|
71
|
+
/**
|
|
72
|
+
* Create TokenInfo from login response
|
|
73
|
+
*
|
|
74
|
+
* @param loginResponse Response from /auth/login endpoint
|
|
75
|
+
* @returns TokenInfo object ready to be stored
|
|
76
|
+
*/
|
|
77
|
+
static fromLoginResponse(loginResponse: {
|
|
78
|
+
access_token: string;
|
|
79
|
+
token_type: string;
|
|
80
|
+
expires_in: number;
|
|
81
|
+
user: {
|
|
82
|
+
username: string;
|
|
83
|
+
role: string;
|
|
84
|
+
};
|
|
85
|
+
}): TokenInfo;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=token-manager.d.ts.map
|