@testany/hephos 0.3.17 → 0.4.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 +29 -0
- package/out/auth/AuthConfig.d.ts +44 -0
- package/out/auth/AuthConfig.d.ts.map +1 -0
- package/out/auth/AuthConfig.js +50 -0
- package/out/auth/AuthConfig.js.map +1 -0
- package/out/auth/AuthService.d.ts +72 -0
- package/out/auth/AuthService.d.ts.map +1 -0
- package/out/auth/AuthService.js +270 -0
- package/out/auth/AuthService.js.map +1 -0
- package/out/auth/CallbackServer.d.ts +15 -0
- package/out/auth/CallbackServer.d.ts.map +1 -0
- package/out/auth/CallbackServer.js +277 -0
- package/out/auth/CallbackServer.js.map +1 -0
- package/out/auth/TokenCache.d.ts +73 -0
- package/out/auth/TokenCache.d.ts.map +1 -0
- package/out/auth/TokenCache.js +174 -0
- package/out/auth/TokenCache.js.map +1 -0
- package/out/auth/index.d.ts +11 -0
- package/out/auth/index.d.ts.map +1 -0
- package/out/auth/index.js +13 -0
- package/out/auth/index.js.map +1 -0
- package/out/auth/types.d.ts +71 -0
- package/out/auth/types.d.ts.map +1 -0
- package/out/auth/types.js +15 -0
- package/out/auth/types.js.map +1 -0
- package/out/cli.d.ts.map +1 -1
- package/out/cli.js +97 -1
- package/out/cli.js.map +1 -1
- package/out/repl/ReplModeInk.d.ts.map +1 -1
- package/out/repl/ReplModeInk.js +109 -3
- package/out/repl/ReplModeInk.js.map +1 -1
- package/package.json +1 -1
- package/patches/ink-text-input+6.0.0.patch +176 -2
package/README.md
CHANGED
|
@@ -34,6 +34,35 @@ agent-chatter
|
|
|
34
34
|
agent-chatter config-example
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
## Authentication
|
|
38
|
+
|
|
39
|
+
Login to HephOS cloud to access team sync and cloud features:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Login via CLI command
|
|
43
|
+
hephos --login cn # Login to CN region (authing.cn)
|
|
44
|
+
hephos --login us # Login to US region (us.authing.co)
|
|
45
|
+
|
|
46
|
+
# Check authentication status
|
|
47
|
+
hephos --auth-status
|
|
48
|
+
|
|
49
|
+
# Logout
|
|
50
|
+
hephos --logout # Logout from active region
|
|
51
|
+
hephos --logout cn # Logout from specific region
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or use REPL commands:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
hephos # Start REPL
|
|
58
|
+
/login cn # Login to CN region
|
|
59
|
+
/login us # Login to US region
|
|
60
|
+
/login status # Check auth status
|
|
61
|
+
/login logout # Logout
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Tokens are cached at `~/.agent-chatter/auth/token-cache.json` with 0600 permissions.
|
|
65
|
+
|
|
37
66
|
## Features
|
|
38
67
|
|
|
39
68
|
- Multi-agent conversation orchestration
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication configuration for US and CN regions
|
|
3
|
+
*/
|
|
4
|
+
import type { AuthRegion } from './types.js';
|
|
5
|
+
/** Region-specific configuration */
|
|
6
|
+
export interface RegionConfig {
|
|
7
|
+
/** Authing application host URL */
|
|
8
|
+
appHost: string;
|
|
9
|
+
/** Authing application ID (audience for JWT) */
|
|
10
|
+
appId: string;
|
|
11
|
+
/** HephOS backend API base URL */
|
|
12
|
+
apiBaseUrl: string;
|
|
13
|
+
/** Display name for UI */
|
|
14
|
+
displayName: string;
|
|
15
|
+
}
|
|
16
|
+
/** Authentication configuration by region */
|
|
17
|
+
export declare const AUTH_CONFIG: Record<AuthRegion, RegionConfig>;
|
|
18
|
+
/** OAuth redirect URI - fixed localhost port */
|
|
19
|
+
export declare const REDIRECT_URI = "http://127.0.0.1:8400/callback";
|
|
20
|
+
/** Callback server port */
|
|
21
|
+
export declare const CALLBACK_PORT = 8400;
|
|
22
|
+
/** OAuth scopes required for login */
|
|
23
|
+
export declare const SCOPES = "openid profile email offline_access";
|
|
24
|
+
/** Login timeout in milliseconds (5 minutes) */
|
|
25
|
+
export declare const LOGIN_TIMEOUT_MS: number;
|
|
26
|
+
/** Token refresh threshold - refresh when less than 5 minutes remaining */
|
|
27
|
+
export declare const REFRESH_THRESHOLD_MS: number;
|
|
28
|
+
/** Token cache file version */
|
|
29
|
+
export declare const TOKEN_CACHE_VERSION = 1;
|
|
30
|
+
/**
|
|
31
|
+
* Get OIDC endpoints for a region
|
|
32
|
+
*/
|
|
33
|
+
export declare function getOIDCEndpoints(region: AuthRegion): {
|
|
34
|
+
authorization: string;
|
|
35
|
+
token: string;
|
|
36
|
+
userInfo: string;
|
|
37
|
+
logout: string;
|
|
38
|
+
jwks: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Validate region string
|
|
42
|
+
*/
|
|
43
|
+
export declare function isValidRegion(region: string): region is AuthRegion;
|
|
44
|
+
//# sourceMappingURL=AuthConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthConfig.d.ts","sourceRoot":"","sources":["../../src/auth/AuthConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,6CAA6C;AAC7C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,CAa/C,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,YAAY,mCAAmC,CAAC;AAE7D,2BAA2B;AAC3B,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,sCAAsC;AACtC,eAAO,MAAM,MAAM,wCAAwC,CAAC;AAE5D,gDAAgD;AAChD,eAAO,MAAM,gBAAgB,QAAgB,CAAC;AAE9C,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,QAAgB,CAAC;AAElD,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU;;;;;;EASlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,UAAU,CAElE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication configuration for US and CN regions
|
|
3
|
+
*/
|
|
4
|
+
/** Authentication configuration by region */
|
|
5
|
+
export const AUTH_CONFIG = {
|
|
6
|
+
cn: {
|
|
7
|
+
appHost: 'https://hephos-cn.authing.cn',
|
|
8
|
+
appId: '69452ae6e3adaa39789bf1a2',
|
|
9
|
+
apiBaseUrl: 'https://api-cn.hephos.testany.com.cn',
|
|
10
|
+
displayName: 'CN (China)',
|
|
11
|
+
},
|
|
12
|
+
us: {
|
|
13
|
+
appHost: 'https://hephos-us.us.authing.co',
|
|
14
|
+
appId: '6948c9d11aa104ecec25d599',
|
|
15
|
+
apiBaseUrl: 'https://api.hephos.ai',
|
|
16
|
+
displayName: 'US (International)',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
/** OAuth redirect URI - fixed localhost port */
|
|
20
|
+
export const REDIRECT_URI = 'http://127.0.0.1:8400/callback';
|
|
21
|
+
/** Callback server port */
|
|
22
|
+
export const CALLBACK_PORT = 8400;
|
|
23
|
+
/** OAuth scopes required for login */
|
|
24
|
+
export const SCOPES = 'openid profile email offline_access';
|
|
25
|
+
/** Login timeout in milliseconds (5 minutes) */
|
|
26
|
+
export const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
27
|
+
/** Token refresh threshold - refresh when less than 5 minutes remaining */
|
|
28
|
+
export const REFRESH_THRESHOLD_MS = 5 * 60 * 1000;
|
|
29
|
+
/** Token cache file version */
|
|
30
|
+
export const TOKEN_CACHE_VERSION = 1;
|
|
31
|
+
/**
|
|
32
|
+
* Get OIDC endpoints for a region
|
|
33
|
+
*/
|
|
34
|
+
export function getOIDCEndpoints(region) {
|
|
35
|
+
const { appHost } = AUTH_CONFIG[region];
|
|
36
|
+
return {
|
|
37
|
+
authorization: `${appHost}/oidc/auth`,
|
|
38
|
+
token: `${appHost}/oidc/token`,
|
|
39
|
+
userInfo: `${appHost}/oidc/me`,
|
|
40
|
+
logout: `${appHost}/oidc/session/end`,
|
|
41
|
+
jwks: `${appHost}/oidc/.well-known/jwks.json`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validate region string
|
|
46
|
+
*/
|
|
47
|
+
export function isValidRegion(region) {
|
|
48
|
+
return region === 'cn' || region === 'us';
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=AuthConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthConfig.js","sourceRoot":"","sources":["../../src/auth/AuthConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAqC;IAC3D,EAAE,EAAE;QACF,OAAO,EAAE,8BAA8B;QACvC,KAAK,EAAE,0BAA0B;QACjC,UAAU,EAAE,sCAAsC;QAClD,WAAW,EAAE,YAAY;KAC1B;IACD,EAAE,EAAE;QACF,OAAO,EAAE,iCAAiC;QAC1C,KAAK,EAAE,0BAA0B;QACjC,UAAU,EAAE,uBAAuB;QACnC,WAAW,EAAE,oBAAoB;KAClC;CACO,CAAC;AAEX,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAE7D,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,sCAAsC;AACtC,MAAM,CAAC,MAAM,MAAM,GAAG,qCAAqC,CAAC;AAE5D,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAElD,+BAA+B;AAC/B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO;QACL,aAAa,EAAE,GAAG,OAAO,YAAY;QACrC,KAAK,EAAE,GAAG,OAAO,aAAa;QAC9B,QAAQ,EAAE,GAAG,OAAO,UAAU;QAC9B,MAAM,EAAE,GAAG,OAAO,mBAAmB;QACrC,IAAI,EAAE,GAAG,OAAO,6BAA6B;KAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication service implementing PKCE OAuth flow with Authing
|
|
3
|
+
*/
|
|
4
|
+
import type { AuthRegion, AuthUrlResult, TokenSet, UserInfo, LoginResult } from './types.js';
|
|
5
|
+
export declare class AuthService {
|
|
6
|
+
private region;
|
|
7
|
+
private endpoints;
|
|
8
|
+
private config;
|
|
9
|
+
constructor(region: AuthRegion);
|
|
10
|
+
/**
|
|
11
|
+
* Generate PKCE parameters (code_verifier, code_challenge, state)
|
|
12
|
+
*/
|
|
13
|
+
private generatePKCE;
|
|
14
|
+
/**
|
|
15
|
+
* Build authorization URL with PKCE
|
|
16
|
+
*/
|
|
17
|
+
buildAuthUrl(): AuthUrlResult;
|
|
18
|
+
/**
|
|
19
|
+
* Exchange authorization code for tokens
|
|
20
|
+
*/
|
|
21
|
+
exchangeCodeForTokens(code: string, verifier: string): Promise<TokenSet>;
|
|
22
|
+
/**
|
|
23
|
+
* Refresh tokens using refresh_token
|
|
24
|
+
*/
|
|
25
|
+
refreshTokens(refreshToken: string): Promise<TokenSet>;
|
|
26
|
+
/**
|
|
27
|
+
* Get user info from Authing userInfo endpoint
|
|
28
|
+
*/
|
|
29
|
+
getUserInfo(accessToken: string): Promise<UserInfo>;
|
|
30
|
+
/**
|
|
31
|
+
* Sync user with HephOS backend
|
|
32
|
+
*/
|
|
33
|
+
syncUser(accessToken: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Open browser for login
|
|
36
|
+
*/
|
|
37
|
+
private openBrowser;
|
|
38
|
+
/**
|
|
39
|
+
* Complete login flow
|
|
40
|
+
*/
|
|
41
|
+
login(): Promise<LoginResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Logout - clear tokens and optionally call logout endpoint
|
|
44
|
+
* For CLI, we just clear local tokens. Browser session cleanup at Authing is optional.
|
|
45
|
+
*/
|
|
46
|
+
logout(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Refresh token if needed
|
|
49
|
+
*/
|
|
50
|
+
refreshIfNeeded(): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Get valid access token (refreshing if needed)
|
|
53
|
+
*/
|
|
54
|
+
getValidAccessToken(): Promise<string | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Check if user is logged in
|
|
57
|
+
*/
|
|
58
|
+
isLoggedIn(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Get current user info (from cache)
|
|
61
|
+
*/
|
|
62
|
+
getCurrentUser(): UserInfo | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create auth service for a region
|
|
66
|
+
*/
|
|
67
|
+
export declare function createAuthService(region: AuthRegion): AuthService;
|
|
68
|
+
/**
|
|
69
|
+
* Mask sensitive token for logging
|
|
70
|
+
*/
|
|
71
|
+
export declare function maskToken(token: string): string;
|
|
72
|
+
//# sourceMappingURL=AuthService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthService.d.ts","sourceRoot":"","sources":["../../src/auth/AuthService.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,MAAM,CAAiC;gBAEnC,MAAM,EAAE,UAAU;IAM9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,YAAY,IAAI,aAAa;IAuB7B;;OAEG;IACG,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IA+B9E;;OAEG;IACG,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyB5D;;OAEG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiBzD;;OAEG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBlD;;OAEG;YACW,WAAW;IAYzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IA2DnC;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBzC;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQnD;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,cAAc,IAAI,QAAQ,GAAG,IAAI;CAGlC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAEjE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication service implementing PKCE OAuth flow with Authing
|
|
3
|
+
*/
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
|
+
import open from 'open';
|
|
6
|
+
import { AUTH_CONFIG, REDIRECT_URI, SCOPES, getOIDCEndpoints, } from './AuthConfig.js';
|
|
7
|
+
import { startCallbackServer } from './CallbackServer.js';
|
|
8
|
+
import { tokenCache } from './TokenCache.js';
|
|
9
|
+
import { AuthError } from './types.js';
|
|
10
|
+
export class AuthService {
|
|
11
|
+
region;
|
|
12
|
+
endpoints;
|
|
13
|
+
config;
|
|
14
|
+
constructor(region) {
|
|
15
|
+
this.region = region;
|
|
16
|
+
this.endpoints = getOIDCEndpoints(region);
|
|
17
|
+
this.config = AUTH_CONFIG[region];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generate PKCE parameters (code_verifier, code_challenge, state)
|
|
21
|
+
*/
|
|
22
|
+
generatePKCE() {
|
|
23
|
+
// Generate code_verifier: 64 bytes of random data as hex (128 chars)
|
|
24
|
+
const verifier = crypto.randomBytes(64).toString('hex');
|
|
25
|
+
// Generate code_challenge: SHA-256 of verifier, base64url encoded
|
|
26
|
+
const hash = crypto.createHash('sha256').update(verifier).digest();
|
|
27
|
+
const challenge = hash
|
|
28
|
+
.toString('base64')
|
|
29
|
+
.replace(/\+/g, '-')
|
|
30
|
+
.replace(/\//g, '_')
|
|
31
|
+
.replace(/=/g, '');
|
|
32
|
+
// Generate state: 16 bytes of random data as hex (32 chars)
|
|
33
|
+
const state = crypto.randomBytes(16).toString('hex');
|
|
34
|
+
return { verifier, challenge, state };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build authorization URL with PKCE
|
|
38
|
+
*/
|
|
39
|
+
buildAuthUrl() {
|
|
40
|
+
const pkce = this.generatePKCE();
|
|
41
|
+
const params = new URLSearchParams({
|
|
42
|
+
client_id: this.config.appId,
|
|
43
|
+
redirect_uri: REDIRECT_URI,
|
|
44
|
+
response_type: 'code',
|
|
45
|
+
scope: SCOPES,
|
|
46
|
+
code_challenge: pkce.challenge,
|
|
47
|
+
code_challenge_method: 'S256',
|
|
48
|
+
state: pkce.state,
|
|
49
|
+
prompt: 'consent', // Required to get refresh_token with offline_access scope
|
|
50
|
+
});
|
|
51
|
+
const url = `${this.endpoints.authorization}?${params.toString()}`;
|
|
52
|
+
return {
|
|
53
|
+
url,
|
|
54
|
+
state: pkce.state,
|
|
55
|
+
verifier: pkce.verifier,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Exchange authorization code for tokens
|
|
60
|
+
*/
|
|
61
|
+
async exchangeCodeForTokens(code, verifier) {
|
|
62
|
+
const body = new URLSearchParams({
|
|
63
|
+
grant_type: 'authorization_code',
|
|
64
|
+
client_id: this.config.appId,
|
|
65
|
+
code,
|
|
66
|
+
redirect_uri: REDIRECT_URI,
|
|
67
|
+
code_verifier: verifier,
|
|
68
|
+
});
|
|
69
|
+
const response = await fetch(this.endpoints.token, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
73
|
+
},
|
|
74
|
+
body: body.toString(),
|
|
75
|
+
});
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
const errorData = await response.json().catch(() => ({}));
|
|
78
|
+
const errorMessage = errorData.error_description
|
|
79
|
+
|| errorData.error
|
|
80
|
+
|| 'Token exchange failed';
|
|
81
|
+
throw new AuthError('AUTH_TOKEN_EXCHANGE_FAILED', `Failed to exchange code for tokens: ${errorMessage}`);
|
|
82
|
+
}
|
|
83
|
+
return await response.json();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Refresh tokens using refresh_token
|
|
87
|
+
*/
|
|
88
|
+
async refreshTokens(refreshToken) {
|
|
89
|
+
const body = new URLSearchParams({
|
|
90
|
+
grant_type: 'refresh_token',
|
|
91
|
+
client_id: this.config.appId,
|
|
92
|
+
refresh_token: refreshToken,
|
|
93
|
+
});
|
|
94
|
+
const response = await fetch(this.endpoints.token, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: {
|
|
97
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
98
|
+
},
|
|
99
|
+
body: body.toString(),
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
throw new AuthError('AUTH_REFRESH_FAILED', 'Failed to refresh token. Please login again.');
|
|
103
|
+
}
|
|
104
|
+
return await response.json();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get user info from Authing userInfo endpoint
|
|
108
|
+
*/
|
|
109
|
+
async getUserInfo(accessToken) {
|
|
110
|
+
const response = await fetch(this.endpoints.userInfo, {
|
|
111
|
+
headers: {
|
|
112
|
+
Authorization: `Bearer ${accessToken}`,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
throw new AuthError('AUTH_TOKEN_EXCHANGE_FAILED', 'Failed to fetch user info');
|
|
117
|
+
}
|
|
118
|
+
return await response.json();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Sync user with HephOS backend
|
|
122
|
+
*/
|
|
123
|
+
async syncUser(accessToken) {
|
|
124
|
+
const response = await fetch(`${this.config.apiBaseUrl}/users/sync`, {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
headers: {
|
|
127
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
},
|
|
130
|
+
body: '{}',
|
|
131
|
+
});
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
// 404 means user hasn't completed onboarding on web
|
|
134
|
+
if (response.status === 404) {
|
|
135
|
+
throw new AuthError('AUTH_USER_SYNC_FAILED', 'User not found. Please complete onboarding on the HephOS website first.');
|
|
136
|
+
}
|
|
137
|
+
// Other errors - warn but don't block
|
|
138
|
+
console.warn(`Warning: User sync failed (${response.status}), but login succeeded.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Open browser for login
|
|
143
|
+
*/
|
|
144
|
+
async openBrowser(url) {
|
|
145
|
+
try {
|
|
146
|
+
await open(url);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Browser failed to open - user will need to manually open URL
|
|
150
|
+
throw new AuthError('AUTH_BROWSER_FAILED', `Failed to open browser. Please visit this URL manually:\n${url}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Complete login flow
|
|
155
|
+
*/
|
|
156
|
+
async login() {
|
|
157
|
+
// Build auth URL with PKCE
|
|
158
|
+
const { url, state, verifier } = this.buildAuthUrl();
|
|
159
|
+
// Start callback server
|
|
160
|
+
const callbackPromise = startCallbackServer();
|
|
161
|
+
// Open browser (with fallback message)
|
|
162
|
+
let browserError = null;
|
|
163
|
+
try {
|
|
164
|
+
await this.openBrowser(url);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
if (err instanceof AuthError) {
|
|
168
|
+
browserError = err;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// If browser failed, show URL but continue waiting for callback
|
|
172
|
+
if (browserError) {
|
|
173
|
+
console.log(`\nPlease open this URL in your browser:\n${url}\n`);
|
|
174
|
+
}
|
|
175
|
+
// Wait for callback
|
|
176
|
+
const callback = await callbackPromise;
|
|
177
|
+
// Validate state
|
|
178
|
+
if (callback.state !== state) {
|
|
179
|
+
throw new AuthError('AUTH_STATE_MISMATCH', 'Security validation failed. Please try again.');
|
|
180
|
+
}
|
|
181
|
+
// Exchange code for tokens
|
|
182
|
+
const tokens = await this.exchangeCodeForTokens(callback.code, verifier);
|
|
183
|
+
// Get user info
|
|
184
|
+
const userInfo = await this.getUserInfo(tokens.access_token);
|
|
185
|
+
// Save tokens to cache
|
|
186
|
+
tokenCache.save(this.region, tokens, userInfo);
|
|
187
|
+
// Try to sync user (non-blocking)
|
|
188
|
+
try {
|
|
189
|
+
await this.syncUser(tokens.access_token);
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
if (err instanceof AuthError && err.code === 'AUTH_USER_SYNC_FAILED') {
|
|
193
|
+
console.warn(`\nWarning: ${err.message}`);
|
|
194
|
+
}
|
|
195
|
+
// Continue - token is saved, user can retry sync later
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
tokens,
|
|
199
|
+
userInfo,
|
|
200
|
+
region: this.region,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Logout - clear tokens and optionally call logout endpoint
|
|
205
|
+
* For CLI, we just clear local tokens. Browser session cleanup at Authing is optional.
|
|
206
|
+
*/
|
|
207
|
+
async logout() {
|
|
208
|
+
tokenCache.clear(this.region);
|
|
209
|
+
// Note: We don't open browser to Authing logout endpoint for CLI.
|
|
210
|
+
// Local token cleanup is sufficient. User can manually logout from Authing if needed.
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Refresh token if needed
|
|
214
|
+
*/
|
|
215
|
+
async refreshIfNeeded() {
|
|
216
|
+
if (!tokenCache.needsRefresh(this.region)) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
const refreshToken = tokenCache.getRefreshToken(this.region);
|
|
220
|
+
if (!refreshToken) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const tokens = await this.refreshTokens(refreshToken);
|
|
225
|
+
const userInfo = await this.getUserInfo(tokens.access_token);
|
|
226
|
+
tokenCache.save(this.region, tokens, userInfo);
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// Refresh failed - token will expire and user will need to re-login
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get valid access token (refreshing if needed)
|
|
236
|
+
*/
|
|
237
|
+
async getValidAccessToken() {
|
|
238
|
+
// Try to refresh if needed
|
|
239
|
+
await this.refreshIfNeeded();
|
|
240
|
+
// Return token if valid
|
|
241
|
+
return tokenCache.getAccessToken(this.region);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Check if user is logged in
|
|
245
|
+
*/
|
|
246
|
+
isLoggedIn() {
|
|
247
|
+
return tokenCache.isValid(this.region);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get current user info (from cache)
|
|
251
|
+
*/
|
|
252
|
+
getCurrentUser() {
|
|
253
|
+
return tokenCache.getUserInfo(this.region);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Create auth service for a region
|
|
258
|
+
*/
|
|
259
|
+
export function createAuthService(region) {
|
|
260
|
+
return new AuthService(region);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Mask sensitive token for logging
|
|
264
|
+
*/
|
|
265
|
+
export function maskToken(token) {
|
|
266
|
+
if (token.length <= 10)
|
|
267
|
+
return '***';
|
|
268
|
+
return `${token.slice(0, 5)}...${token.slice(-5)}`;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=AuthService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../src/auth/AuthService.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAUvC,MAAM,OAAO,WAAW;IACd,MAAM,CAAa;IACnB,SAAS,CAAsC;IAC/C,MAAM,CAAiC;IAE/C,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,qEAAqE;QACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAExD,kEAAkE;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI;aACnB,QAAQ,CAAC,QAAQ,CAAC;aAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAErB,4DAA4D;QAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEjC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,MAAM;YACrB,KAAK,EAAE,MAAM;YACb,cAAc,EAAE,IAAI,CAAC,SAAS;YAC9B,qBAAqB,EAAE,MAAM;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,SAAS,EAAE,0DAA0D;SAC9E,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAEnE,OAAO;YACL,GAAG;YACH,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,IAAY,EAAE,QAAgB;QACxD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;YAC/B,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B,IAAI;YACJ,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,QAAQ;SACxB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;YACjD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;aACpD;YACD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1D,MAAM,YAAY,GAAI,SAA4C,CAAC,iBAAiB;mBAC9E,SAAgC,CAAC,KAAK;mBACvC,uBAAuB,CAAC;YAC7B,MAAM,IAAI,SAAS,CACjB,4BAA4B,EAC5B,uCAAuC,YAAY,EAAE,CACtD,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAc,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,YAAoB;QACtC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;YAC/B,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YAC5B,aAAa,EAAE,YAAY;SAC5B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;YACjD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;aACpD;YACD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,8CAA8C,CAC/C,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAc,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB;QACnC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YACpD,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;aACvC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,SAAS,CACjB,4BAA4B,EAC5B,2BAA2B,CAC5B,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAc,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,WAAmB;QAChC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,aAAa,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,WAAW,EAAE;gBACxC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,oDAAoD;YACpD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,yEAAyE,CAC1E,CAAC;YACJ,CAAC;YACD,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,8BAA8B,QAAQ,CAAC,MAAM,yBAAyB,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,GAAW;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;YAC/D,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,4DAA4D,GAAG,EAAE,CAClE,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,2BAA2B;QAC3B,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAErD,wBAAwB;QACxB,MAAM,eAAe,GAAG,mBAAmB,EAAE,CAAC;QAE9C,uCAAuC;QACvC,IAAI,YAAY,GAAqB,IAAI,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;gBAC7B,YAAY,GAAG,GAAG,CAAC;YACrB,CAAC;QACH,CAAC;QAED,gEAAgE;QAChE,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,4CAA4C,GAAG,IAAI,CAAC,CAAC;QACnE,CAAC;QAED,oBAAoB;QACpB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC;QAEvC,iBAAiB;QACjB,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC7B,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,+CAA+C,CAChD,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEzE,gBAAgB;QAChB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAE7D,uBAAuB;QACvB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE/C,kCAAkC;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,uDAAuD;QACzD,CAAC;QAED,OAAO;YACL,MAAM;YACN,QAAQ;YACR,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM;QACV,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,kEAAkE;QAClE,sFAAsF;IACxF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,YAAY,GAAG,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC7D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB;QACvB,2BAA2B;QAC3B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE7B,wBAAwB;QACxB,OAAO,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server to receive OAuth callback
|
|
3
|
+
* Listens on 127.0.0.1:8400 for security (localhost only)
|
|
4
|
+
*/
|
|
5
|
+
import type { CallbackResult } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Start a local HTTP server to receive OAuth callback
|
|
8
|
+
* Returns a promise that resolves with the authorization code and state
|
|
9
|
+
*/
|
|
10
|
+
export declare function startCallbackServer(): Promise<CallbackResult>;
|
|
11
|
+
/**
|
|
12
|
+
* Check if port is available
|
|
13
|
+
*/
|
|
14
|
+
export declare function isPortAvailable(port?: number): Promise<boolean>;
|
|
15
|
+
//# sourceMappingURL=CallbackServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackServer.d.ts","sourceRoot":"","sources":["../../src/auth/CallbackServer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkLjD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,cAAc,CAAC,CAoG7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAY9E"}
|