binoauth 0.0.10 → 0.0.12
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 +359 -165
- package/dist/core/src/admin/client.d.ts +203 -0
- package/dist/core/src/admin/client.d.ts.map +1 -0
- package/dist/core/src/admin/client.js +391 -0
- package/dist/core/src/admin/client.js.map +1 -0
- package/dist/core/src/admin/index.d.ts +6 -0
- package/dist/core/src/admin/index.d.ts.map +1 -0
- package/dist/core/src/admin/index.js +5 -0
- package/dist/core/src/admin/index.js.map +1 -0
- package/dist/core/src/admin/types.d.ts +412 -0
- package/dist/core/src/admin/types.d.ts.map +1 -0
- package/dist/core/src/admin/types.js +5 -0
- package/dist/core/src/admin/types.js.map +1 -0
- package/dist/core/src/auth/client.d.ts +330 -0
- package/dist/core/src/auth/client.d.ts.map +1 -0
- package/dist/core/src/auth/client.js +408 -0
- package/dist/core/src/auth/client.js.map +1 -0
- package/dist/core/src/auth/error.d.ts +113 -0
- package/dist/core/src/auth/error.d.ts.map +1 -0
- package/dist/core/src/auth/error.js +257 -0
- package/dist/core/src/auth/error.js.map +1 -0
- package/dist/core/src/auth/flows/base-flow.d.ts +98 -0
- package/dist/core/src/auth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/auth/flows/base-flow.js +182 -0
- package/dist/core/src/auth/flows/base-flow.js.map +1 -0
- package/dist/core/src/auth/flows/magic-link.d.ts +175 -0
- package/dist/core/src/auth/flows/magic-link.d.ts.map +1 -0
- package/dist/core/src/auth/flows/magic-link.js +228 -0
- package/dist/core/src/auth/flows/magic-link.js.map +1 -0
- package/dist/core/src/auth/flows/mfa.d.ts +81 -0
- package/dist/core/src/auth/flows/mfa.d.ts.map +1 -0
- package/dist/core/src/auth/flows/mfa.js +103 -0
- package/dist/core/src/auth/flows/mfa.js.map +1 -0
- package/dist/core/src/auth/flows/otp.d.ts +172 -0
- package/dist/core/src/auth/flows/otp.d.ts.map +1 -0
- package/dist/core/src/auth/flows/otp.js +222 -0
- package/dist/core/src/auth/flows/otp.js.map +1 -0
- package/dist/core/src/auth/flows/password.d.ts +242 -0
- package/dist/core/src/auth/flows/password.d.ts.map +1 -0
- package/dist/core/src/auth/flows/password.js +344 -0
- package/dist/core/src/auth/flows/password.js.map +1 -0
- package/dist/core/src/auth/flows/social.d.ts +209 -0
- package/dist/core/src/auth/flows/social.d.ts.map +1 -0
- package/dist/core/src/auth/flows/social.js +284 -0
- package/dist/core/src/auth/flows/social.js.map +1 -0
- package/dist/core/src/auth/index.d.ts +19 -0
- package/dist/core/src/auth/index.d.ts.map +1 -0
- package/dist/core/src/auth/index.js +32 -0
- package/dist/core/src/auth/index.js.map +1 -0
- package/dist/core/src/auth/types.d.ts +151 -0
- package/dist/core/src/auth/types.d.ts.map +1 -0
- package/dist/core/src/auth/types.js +7 -0
- package/dist/core/src/auth/types.js.map +1 -0
- package/dist/core/src/index.d.ts +53 -49
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/index.js +61 -343
- package/dist/core/src/index.js.map +1 -1
- package/dist/core/src/oauth/client.d.ts +322 -0
- package/dist/core/src/oauth/client.d.ts.map +1 -0
- package/dist/core/src/oauth/client.js +491 -0
- package/dist/core/src/oauth/client.js.map +1 -0
- package/dist/core/src/oauth/error.d.ts +18 -0
- package/dist/core/src/oauth/error.d.ts.map +1 -0
- package/dist/core/src/oauth/error.js +24 -0
- package/dist/core/src/oauth/error.js.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts +122 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.js +278 -0
- package/dist/core/src/oauth/flows/authorization-code.js.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts +17 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.js +107 -0
- package/dist/core/src/oauth/flows/base-flow.js.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts +72 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.js +100 -0
- package/dist/core/src/oauth/flows/client-credentials.js.map +1 -0
- package/dist/core/src/oauth/flows/device-code.d.ts +108 -0
- package/dist/core/src/oauth/flows/device-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/device-code.js +193 -0
- package/dist/core/src/oauth/flows/device-code.js.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts +59 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.js +105 -0
- package/dist/core/src/oauth/flows/refresh-token.js.map +1 -0
- package/dist/core/src/oauth/index.d.ts +12 -0
- package/dist/core/src/oauth/index.d.ts.map +1 -0
- package/dist/core/src/oauth/index.js +11 -0
- package/dist/core/src/oauth/index.js.map +1 -0
- package/dist/core/src/oauth/storage/encryption.d.ts +12 -0
- package/dist/core/src/oauth/storage/encryption.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/encryption.js +76 -0
- package/dist/core/src/oauth/storage/encryption.js.map +1 -0
- package/dist/core/src/oauth/storage/index.d.ts +201 -0
- package/dist/core/src/oauth/storage/index.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/index.js +322 -0
- package/dist/core/src/oauth/storage/index.js.map +1 -0
- package/dist/core/src/oauth/storage/strategies.d.ts +34 -0
- package/dist/core/src/oauth/storage/strategies.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/strategies.js +100 -0
- package/dist/core/src/oauth/storage/strategies.js.map +1 -0
- package/dist/core/src/oauth/types.d.ts +261 -0
- package/dist/core/src/oauth/types.d.ts.map +1 -0
- package/dist/core/src/oauth/types.js +39 -0
- package/dist/core/src/oauth/types.js.map +1 -0
- package/dist/core/src/oauth/utils.d.ts +56 -0
- package/dist/core/src/oauth/utils.d.ts.map +1 -0
- package/dist/core/src/oauth/utils.js +140 -0
- package/dist/core/src/oauth/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -0,0 +1,108 @@
|
|
1
|
+
import type { AuthConfig, DeviceCodeResponse } from "../types";
|
2
|
+
import { TokenStorage } from "../storage";
|
3
|
+
import { BaseFlow } from "./base-flow";
|
4
|
+
import type { OAuth2Api } from "@binoauth/tenant-sdk";
|
5
|
+
/**
|
6
|
+
* OAuth 2.0 Device Authorization Grant (Device Code Flow)
|
7
|
+
*
|
8
|
+
* This flow is designed for devices that either lack a browser or have
|
9
|
+
* limited input capabilities (smart TVs, IoT devices, CLI tools).
|
10
|
+
*
|
11
|
+
* @example
|
12
|
+
* ```typescript
|
13
|
+
* const flow = new DeviceCodeFlow(config, storage, oauthApi);
|
14
|
+
*
|
15
|
+
* // Step 1: Request device code
|
16
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
17
|
+
* console.log(`Go to: ${deviceAuth.verification_uri}`);
|
18
|
+
* console.log(`Enter code: ${deviceAuth.user_code}`);
|
19
|
+
*
|
20
|
+
* // Step 2: Poll for token (user enters code on another device)
|
21
|
+
* const pollInterval = deviceAuth.interval * 1000; // Convert to milliseconds
|
22
|
+
* const maxAttempts = Math.floor(deviceAuth.expires_in / deviceAuth.interval);
|
23
|
+
*
|
24
|
+
* for (let i = 0; i < maxAttempts; i++) {
|
25
|
+
* try {
|
26
|
+
* await flow.pollForToken(deviceAuth.device_code);
|
27
|
+
* console.log('Device authenticated successfully!');
|
28
|
+
* break;
|
29
|
+
* } catch (error) {
|
30
|
+
* if (error.code === 'authorization_pending') {
|
31
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval));
|
32
|
+
* continue;
|
33
|
+
* }
|
34
|
+
* throw error; // Other errors should not be retried
|
35
|
+
* }
|
36
|
+
* }
|
37
|
+
* ```
|
38
|
+
*/
|
39
|
+
export declare class DeviceCodeFlow extends BaseFlow {
|
40
|
+
constructor(config: AuthConfig, storage: TokenStorage, oauthApi?: OAuth2Api);
|
41
|
+
/**
|
42
|
+
* Initiates the device authorization flow
|
43
|
+
*
|
44
|
+
* Requests a device code and user code from the authorization server.
|
45
|
+
* The user will need to visit the verification URI and enter the user code.
|
46
|
+
*
|
47
|
+
* @returns Promise resolving to device authorization response
|
48
|
+
*
|
49
|
+
* @example
|
50
|
+
* ```typescript
|
51
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
52
|
+
*
|
53
|
+
* console.log(`Please visit: ${deviceAuth.verification_uri}`);
|
54
|
+
* console.log(`And enter this code: ${deviceAuth.user_code}`);
|
55
|
+
* console.log(`This code expires in ${deviceAuth.expires_in} seconds`);
|
56
|
+
*
|
57
|
+
* // Example response:
|
58
|
+
* // {
|
59
|
+
* // device_code: "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
|
60
|
+
* // user_code: "WDJB-MJHT",
|
61
|
+
* // verification_uri: "https://auth.binoauth.com/auth/device",
|
62
|
+
* // expires_in: 1800,
|
63
|
+
* // interval: 5
|
64
|
+
* // }
|
65
|
+
* ```
|
66
|
+
*
|
67
|
+
* @throws {AuthError} When device code request fails
|
68
|
+
*/
|
69
|
+
requestDeviceCode(): Promise<DeviceCodeResponse>;
|
70
|
+
/**
|
71
|
+
* Polls for token using the device code
|
72
|
+
*
|
73
|
+
* Continuously checks if the user has authorized the device by entering
|
74
|
+
* the user code. Should be called in a loop with appropriate intervals.
|
75
|
+
*
|
76
|
+
* @param deviceCode - The device code received from requestDeviceCode()
|
77
|
+
*
|
78
|
+
* @example
|
79
|
+
* ```typescript
|
80
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
81
|
+
* const pollInterval = deviceAuth.interval * 1000; // Convert to milliseconds
|
82
|
+
*
|
83
|
+
* // Poll until authorized or expired
|
84
|
+
* while (true) {
|
85
|
+
* try {
|
86
|
+
* await flow.pollForToken(deviceAuth.device_code);
|
87
|
+
* console.log('Authorization successful!');
|
88
|
+
* break;
|
89
|
+
* } catch (error) {
|
90
|
+
* if (error.code === 'authorization_pending') {
|
91
|
+
* console.log('Waiting for user authorization...');
|
92
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval));
|
93
|
+
* continue;
|
94
|
+
* } else if (error.code === 'slow_down') {
|
95
|
+
* console.log('Polling too fast, slowing down...');
|
96
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval * 2));
|
97
|
+
* continue;
|
98
|
+
* }
|
99
|
+
* throw error; // Other errors are terminal
|
100
|
+
* }
|
101
|
+
* }
|
102
|
+
* ```
|
103
|
+
*
|
104
|
+
* @throws {AuthError} When token polling fails or device code expires
|
105
|
+
*/
|
106
|
+
pollForToken(deviceCode: string): Promise<void>;
|
107
|
+
}
|
108
|
+
//# sourceMappingURL=device-code.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"device-code.d.ts","sourceRoot":"","sources":["../../../../../src/oauth/flows/device-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,SAAS;IAI3E;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAkFtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiCtD"}
|
@@ -0,0 +1,193 @@
|
|
1
|
+
import { TokenStorage } from "../storage";
|
2
|
+
import { AuthError, ErrorCode } from "../error";
|
3
|
+
import { BaseFlow } from "./base-flow";
|
4
|
+
/**
|
5
|
+
* OAuth 2.0 Device Authorization Grant (Device Code Flow)
|
6
|
+
*
|
7
|
+
* This flow is designed for devices that either lack a browser or have
|
8
|
+
* limited input capabilities (smart TVs, IoT devices, CLI tools).
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```typescript
|
12
|
+
* const flow = new DeviceCodeFlow(config, storage, oauthApi);
|
13
|
+
*
|
14
|
+
* // Step 1: Request device code
|
15
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
16
|
+
* console.log(`Go to: ${deviceAuth.verification_uri}`);
|
17
|
+
* console.log(`Enter code: ${deviceAuth.user_code}`);
|
18
|
+
*
|
19
|
+
* // Step 2: Poll for token (user enters code on another device)
|
20
|
+
* const pollInterval = deviceAuth.interval * 1000; // Convert to milliseconds
|
21
|
+
* const maxAttempts = Math.floor(deviceAuth.expires_in / deviceAuth.interval);
|
22
|
+
*
|
23
|
+
* for (let i = 0; i < maxAttempts; i++) {
|
24
|
+
* try {
|
25
|
+
* await flow.pollForToken(deviceAuth.device_code);
|
26
|
+
* console.log('Device authenticated successfully!');
|
27
|
+
* break;
|
28
|
+
* } catch (error) {
|
29
|
+
* if (error.code === 'authorization_pending') {
|
30
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval));
|
31
|
+
* continue;
|
32
|
+
* }
|
33
|
+
* throw error; // Other errors should not be retried
|
34
|
+
* }
|
35
|
+
* }
|
36
|
+
* ```
|
37
|
+
*/
|
38
|
+
export class DeviceCodeFlow extends BaseFlow {
|
39
|
+
constructor(config, storage, oauthApi) {
|
40
|
+
super(config, storage, oauthApi);
|
41
|
+
}
|
42
|
+
/**
|
43
|
+
* Initiates the device authorization flow
|
44
|
+
*
|
45
|
+
* Requests a device code and user code from the authorization server.
|
46
|
+
* The user will need to visit the verification URI and enter the user code.
|
47
|
+
*
|
48
|
+
* @returns Promise resolving to device authorization response
|
49
|
+
*
|
50
|
+
* @example
|
51
|
+
* ```typescript
|
52
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
53
|
+
*
|
54
|
+
* console.log(`Please visit: ${deviceAuth.verification_uri}`);
|
55
|
+
* console.log(`And enter this code: ${deviceAuth.user_code}`);
|
56
|
+
* console.log(`This code expires in ${deviceAuth.expires_in} seconds`);
|
57
|
+
*
|
58
|
+
* // Example response:
|
59
|
+
* // {
|
60
|
+
* // device_code: "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
|
61
|
+
* // user_code: "WDJB-MJHT",
|
62
|
+
* // verification_uri: "https://auth.binoauth.com/auth/device",
|
63
|
+
* // expires_in: 1800,
|
64
|
+
* // interval: 5
|
65
|
+
* // }
|
66
|
+
* ```
|
67
|
+
*
|
68
|
+
* @throws {AuthError} When device code request fails
|
69
|
+
*/
|
70
|
+
async requestDeviceCode() {
|
71
|
+
if (this.oauthApi) {
|
72
|
+
try {
|
73
|
+
const response = await this.oauthApi.deviceAuthorizationApiV1OauthDeviceCodePost({
|
74
|
+
deviceAuthorizationRequest: {
|
75
|
+
clientId: this.config.clientId,
|
76
|
+
}
|
77
|
+
});
|
78
|
+
return {
|
79
|
+
device_code: response.deviceCode,
|
80
|
+
user_code: response.userCode,
|
81
|
+
verification_uri: `${this.getIssuerFromEndpoint()}/auth/device`,
|
82
|
+
verification_uri_complete: `${this.getIssuerFromEndpoint()}/auth/device?user_code=${response.userCode}`,
|
83
|
+
expires_in: response.expiresIn,
|
84
|
+
interval: response.interval || 5,
|
85
|
+
};
|
86
|
+
}
|
87
|
+
catch (error) {
|
88
|
+
throw new AuthError("Device code request failed", ErrorCode.TokenExchangeFailed, error.message || "Tenant SDK request failed");
|
89
|
+
}
|
90
|
+
}
|
91
|
+
// Fallback to manual implementation
|
92
|
+
if (!this.config.authorizeEndpoint) {
|
93
|
+
throw new AuthError("Missing authorizeEndpoint in config", ErrorCode.InvalidConfig);
|
94
|
+
}
|
95
|
+
const deviceEndpoint = this.config.authorizeEndpoint.replace('/oauth/authorize', '/oauth/device/code');
|
96
|
+
const response = await fetch(deviceEndpoint, {
|
97
|
+
method: "POST",
|
98
|
+
headers: {
|
99
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
100
|
+
},
|
101
|
+
body: new URLSearchParams({
|
102
|
+
client_id: this.config.clientId,
|
103
|
+
scope: this.config.scope,
|
104
|
+
}).toString(),
|
105
|
+
});
|
106
|
+
if (!response.ok) {
|
107
|
+
let errorDetail = "Device code request failed";
|
108
|
+
try {
|
109
|
+
const error = await response.json();
|
110
|
+
errorDetail = error.detail || error.error_description || error.error || errorDetail;
|
111
|
+
}
|
112
|
+
catch (e) {
|
113
|
+
errorDetail = await response.text();
|
114
|
+
}
|
115
|
+
throw new AuthError("Device code request failed", ErrorCode.TokenExchangeFailed, errorDetail);
|
116
|
+
}
|
117
|
+
const deviceCode = await response.json();
|
118
|
+
if (!deviceCode.device_code || !deviceCode.user_code || !deviceCode.verification_uri) {
|
119
|
+
throw new AuthError("Invalid device code response", ErrorCode.TokenExchangeFailed);
|
120
|
+
}
|
121
|
+
return {
|
122
|
+
device_code: deviceCode.device_code,
|
123
|
+
user_code: deviceCode.user_code,
|
124
|
+
verification_uri: deviceCode.verification_uri,
|
125
|
+
verification_uri_complete: deviceCode.verification_uri_complete,
|
126
|
+
expires_in: deviceCode.expires_in || 600,
|
127
|
+
interval: deviceCode.interval || 5,
|
128
|
+
};
|
129
|
+
}
|
130
|
+
/**
|
131
|
+
* Polls for token using the device code
|
132
|
+
*
|
133
|
+
* Continuously checks if the user has authorized the device by entering
|
134
|
+
* the user code. Should be called in a loop with appropriate intervals.
|
135
|
+
*
|
136
|
+
* @param deviceCode - The device code received from requestDeviceCode()
|
137
|
+
*
|
138
|
+
* @example
|
139
|
+
* ```typescript
|
140
|
+
* const deviceAuth = await flow.requestDeviceCode();
|
141
|
+
* const pollInterval = deviceAuth.interval * 1000; // Convert to milliseconds
|
142
|
+
*
|
143
|
+
* // Poll until authorized or expired
|
144
|
+
* while (true) {
|
145
|
+
* try {
|
146
|
+
* await flow.pollForToken(deviceAuth.device_code);
|
147
|
+
* console.log('Authorization successful!');
|
148
|
+
* break;
|
149
|
+
* } catch (error) {
|
150
|
+
* if (error.code === 'authorization_pending') {
|
151
|
+
* console.log('Waiting for user authorization...');
|
152
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval));
|
153
|
+
* continue;
|
154
|
+
* } else if (error.code === 'slow_down') {
|
155
|
+
* console.log('Polling too fast, slowing down...');
|
156
|
+
* await new Promise(resolve => setTimeout(resolve, pollInterval * 2));
|
157
|
+
* continue;
|
158
|
+
* }
|
159
|
+
* throw error; // Other errors are terminal
|
160
|
+
* }
|
161
|
+
* }
|
162
|
+
* ```
|
163
|
+
*
|
164
|
+
* @throws {AuthError} When token polling fails or device code expires
|
165
|
+
*/
|
166
|
+
async pollForToken(deviceCode) {
|
167
|
+
if (this.oauthApi) {
|
168
|
+
try {
|
169
|
+
const response = await this.oauthApi.getTokensApiV1OauthTokenPost({
|
170
|
+
tokenRequest: {
|
171
|
+
grantType: "urn:ietf:params:oauth:grant-type:device_code",
|
172
|
+
deviceCode: deviceCode,
|
173
|
+
clientId: this.config.clientId,
|
174
|
+
}
|
175
|
+
});
|
176
|
+
const tokenSet = this.convertTenantTokenResponse(response);
|
177
|
+
await this.storage.setTokens(tokenSet);
|
178
|
+
return;
|
179
|
+
}
|
180
|
+
catch (error) {
|
181
|
+
throw new AuthError("Device token polling failed", ErrorCode.TokenExchangeFailed, error.message || "Tenant SDK request failed");
|
182
|
+
}
|
183
|
+
}
|
184
|
+
// Fallback to base implementation
|
185
|
+
const tokenSet = await this.makeTokenRequest({
|
186
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
187
|
+
device_code: deviceCode,
|
188
|
+
client_id: this.config.clientId,
|
189
|
+
});
|
190
|
+
await this.storage.setTokens(tokenSet);
|
191
|
+
}
|
192
|
+
}
|
193
|
+
//# sourceMappingURL=device-code.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"device-code.js","sourceRoot":"","sources":["../../../../../src/oauth/flows/device-code.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import type { AuthConfig } from "../types";
|
2
|
+
import { TokenStorage } from "../storage";
|
3
|
+
import { BaseFlow } from "./base-flow";
|
4
|
+
import type { OAuth2Api } from "@binoauth/tenant-sdk";
|
5
|
+
/**
|
6
|
+
* OAuth 2.0 Refresh Token Flow
|
7
|
+
*
|
8
|
+
* Handles refreshing expired access tokens using refresh tokens.
|
9
|
+
* Implements automatic retry logic and prevents concurrent refresh operations.
|
10
|
+
*
|
11
|
+
* @example
|
12
|
+
* ```typescript
|
13
|
+
* const flow = new RefreshTokenFlow(config, storage, oauthApi);
|
14
|
+
*
|
15
|
+
* // Manual refresh
|
16
|
+
* await flow.refreshTokens();
|
17
|
+
*
|
18
|
+
* // Refresh with specific token
|
19
|
+
* await flow.refreshTokens('existing_refresh_token');
|
20
|
+
*
|
21
|
+
* // The flow automatically handles:
|
22
|
+
* // - Rate limiting
|
23
|
+
* // - Concurrent request prevention
|
24
|
+
* // - Token storage updates
|
25
|
+
* ```
|
26
|
+
*/
|
27
|
+
export declare class RefreshTokenFlow extends BaseFlow {
|
28
|
+
private refreshPromise;
|
29
|
+
constructor(config: AuthConfig, storage: TokenStorage, oauthApi?: OAuth2Api);
|
30
|
+
/**
|
31
|
+
* Refreshes access tokens using a refresh token
|
32
|
+
*
|
33
|
+
* If no refresh token is provided, it will attempt to use the stored refresh token.
|
34
|
+
* Prevents concurrent refresh operations by reusing in-flight requests.
|
35
|
+
*
|
36
|
+
* @param refreshToken - Optional refresh token to use (uses stored token if not provided)
|
37
|
+
*
|
38
|
+
* @example
|
39
|
+
* ```typescript
|
40
|
+
* // Use stored refresh token
|
41
|
+
* await flow.refreshTokens();
|
42
|
+
*
|
43
|
+
* // Use specific refresh token
|
44
|
+
* await flow.refreshTokens('refresh_token_value');
|
45
|
+
*
|
46
|
+
* // Check if token was refreshed successfully
|
47
|
+
* const accessToken = await storage.getAccessToken();
|
48
|
+
* if (accessToken && !storage.isTokenExpired(accessToken)) {
|
49
|
+
* console.log('Token refreshed successfully');
|
50
|
+
* }
|
51
|
+
* ```
|
52
|
+
*
|
53
|
+
* @throws {AuthError} When no refresh token is available
|
54
|
+
* @throws {AuthError} When token refresh fails
|
55
|
+
*/
|
56
|
+
refreshTokens(refreshToken?: string): Promise<void>;
|
57
|
+
private performTokenRefresh;
|
58
|
+
}
|
59
|
+
//# sourceMappingURL=refresh-token.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"refresh-token.d.ts","sourceRoot":"","sources":["../../../../../src/oauth/flows/refresh-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,OAAO,CAAC,cAAc,CAA8B;gBAExC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,SAAS;IAI3E;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,aAAa,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAuB3C,mBAAmB;CAyClC"}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
import { TokenStorage } from "../storage";
|
2
|
+
import { AuthError, ErrorCode } from "../error";
|
3
|
+
import { BaseFlow } from "./base-flow";
|
4
|
+
/**
|
5
|
+
* OAuth 2.0 Refresh Token Flow
|
6
|
+
*
|
7
|
+
* Handles refreshing expired access tokens using refresh tokens.
|
8
|
+
* Implements automatic retry logic and prevents concurrent refresh operations.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```typescript
|
12
|
+
* const flow = new RefreshTokenFlow(config, storage, oauthApi);
|
13
|
+
*
|
14
|
+
* // Manual refresh
|
15
|
+
* await flow.refreshTokens();
|
16
|
+
*
|
17
|
+
* // Refresh with specific token
|
18
|
+
* await flow.refreshTokens('existing_refresh_token');
|
19
|
+
*
|
20
|
+
* // The flow automatically handles:
|
21
|
+
* // - Rate limiting
|
22
|
+
* // - Concurrent request prevention
|
23
|
+
* // - Token storage updates
|
24
|
+
* ```
|
25
|
+
*/
|
26
|
+
export class RefreshTokenFlow extends BaseFlow {
|
27
|
+
refreshPromise = null;
|
28
|
+
constructor(config, storage, oauthApi) {
|
29
|
+
super(config, storage, oauthApi);
|
30
|
+
}
|
31
|
+
/**
|
32
|
+
* Refreshes access tokens using a refresh token
|
33
|
+
*
|
34
|
+
* If no refresh token is provided, it will attempt to use the stored refresh token.
|
35
|
+
* Prevents concurrent refresh operations by reusing in-flight requests.
|
36
|
+
*
|
37
|
+
* @param refreshToken - Optional refresh token to use (uses stored token if not provided)
|
38
|
+
*
|
39
|
+
* @example
|
40
|
+
* ```typescript
|
41
|
+
* // Use stored refresh token
|
42
|
+
* await flow.refreshTokens();
|
43
|
+
*
|
44
|
+
* // Use specific refresh token
|
45
|
+
* await flow.refreshTokens('refresh_token_value');
|
46
|
+
*
|
47
|
+
* // Check if token was refreshed successfully
|
48
|
+
* const accessToken = await storage.getAccessToken();
|
49
|
+
* if (accessToken && !storage.isTokenExpired(accessToken)) {
|
50
|
+
* console.log('Token refreshed successfully');
|
51
|
+
* }
|
52
|
+
* ```
|
53
|
+
*
|
54
|
+
* @throws {AuthError} When no refresh token is available
|
55
|
+
* @throws {AuthError} When token refresh fails
|
56
|
+
*/
|
57
|
+
async refreshTokens(refreshToken) {
|
58
|
+
if (this.refreshPromise) {
|
59
|
+
await this.refreshPromise;
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
const tokenToUse = refreshToken || (await this.storage.getRefreshToken())?.value;
|
63
|
+
if (!tokenToUse) {
|
64
|
+
throw new AuthError("No refresh token available", ErrorCode.MissingRefreshToken);
|
65
|
+
}
|
66
|
+
this.refreshPromise = this.performTokenRefresh(tokenToUse);
|
67
|
+
try {
|
68
|
+
await this.refreshPromise;
|
69
|
+
}
|
70
|
+
finally {
|
71
|
+
this.refreshPromise = null;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
async performTokenRefresh(refreshToken) {
|
75
|
+
if (!refreshToken) {
|
76
|
+
throw new AuthError("No refresh token provided", ErrorCode.MissingRefreshToken);
|
77
|
+
}
|
78
|
+
this.checkRateLimit("refresh", 5, 10 * 60 * 1000);
|
79
|
+
if (this.oauthApi) {
|
80
|
+
try {
|
81
|
+
const response = await this.oauthApi.getTokensApiV1OauthTokenPost({
|
82
|
+
tokenRequest: {
|
83
|
+
grantType: "refresh_token",
|
84
|
+
refreshToken: refreshToken,
|
85
|
+
clientId: this.config.clientId,
|
86
|
+
}
|
87
|
+
});
|
88
|
+
const tokenSet = this.convertTenantTokenResponse(response);
|
89
|
+
await this.storage.setTokens(tokenSet);
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
catch (error) {
|
93
|
+
throw new AuthError("Token refresh failed", ErrorCode.TokenRefreshFailed, error.message || "Tenant SDK request failed");
|
94
|
+
}
|
95
|
+
}
|
96
|
+
// Fallback to manual implementation
|
97
|
+
const tokenSet = await this.makeTokenRequest({
|
98
|
+
grant_type: "refresh_token",
|
99
|
+
refresh_token: refreshToken,
|
100
|
+
client_id: this.config.clientId,
|
101
|
+
});
|
102
|
+
await this.storage.setTokens(tokenSet);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
//# sourceMappingURL=refresh-token.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"refresh-token.js","sourceRoot":"","sources":["../../../../../src/oauth/flows/refresh-token.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IACpC,cAAc,GAAyB,IAAI,CAAC;IAEpD,YAAY,MAAkB,EAAE,OAAqB,EAAE,QAAoB;QACzE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,KAAK,CAAC,aAAa,CAAC,YAAqB;QACvC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,cAAc,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,CAAC;QACjF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,SAAS,CACjB,4BAA4B,EAC5B,SAAS,CAAC,mBAAmB,CAC9B,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAE3D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,cAAc,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,YAAoB;QACpD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,SAAS,CACjB,2BAA2B,EAC3B,SAAS,CAAC,mBAAmB,CAC9B,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC;oBAChE,YAAY,EAAE;wBACZ,SAAS,EAAE,eAAe;wBAC1B,YAAY,EAAE,YAAY;wBAC1B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;qBAC/B;iBACF,CAAC,CAAC;gBAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;gBAC3D,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBACvC,OAAO;YACT,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,SAAS,CAAC,kBAAkB,EAC5B,KAAK,CAAC,OAAO,IAAI,2BAA2B,CAC7C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC;YAC3C,UAAU,EAAE,eAAe;YAC3B,aAAa,EAAE,YAAY;YAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;SAChC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACF"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export * from "./types";
|
2
|
+
export * from "./error";
|
3
|
+
export * from "./utils";
|
4
|
+
export { TokenStorage } from "./storage";
|
5
|
+
export { BinoAuthOAuth } from "./client";
|
6
|
+
export { AuthorizationCodeFlow } from "./flows/authorization-code";
|
7
|
+
export { RefreshTokenFlow } from "./flows/refresh-token";
|
8
|
+
export { DeviceCodeFlow } from "./flows/device-code";
|
9
|
+
export { ClientCredentialsFlow } from "./flows/client-credentials";
|
10
|
+
export type { BinoAuthConfig } from "./types";
|
11
|
+
export { createAuthConfigFromIssuer } from "./types";
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC"}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export * from "./types";
|
2
|
+
export * from "./error";
|
3
|
+
export * from "./utils";
|
4
|
+
export { TokenStorage } from "./storage";
|
5
|
+
export { BinoAuthOAuth } from "./client";
|
6
|
+
export { AuthorizationCodeFlow } from "./flows/authorization-code";
|
7
|
+
export { RefreshTokenFlow } from "./flows/refresh-token";
|
8
|
+
export { DeviceCodeFlow } from "./flows/device-code";
|
9
|
+
export { ClientCredentialsFlow } from "./flows/client-credentials";
|
10
|
+
export { createAuthConfigFromIssuer } from "./types";
|
11
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export declare class Encryptor {
|
2
|
+
private key;
|
3
|
+
private crypto;
|
4
|
+
initialize(key: string): Promise<void>;
|
5
|
+
private hashKey;
|
6
|
+
private importKey;
|
7
|
+
encrypt(data: string): Promise<string>;
|
8
|
+
decrypt(encryptedData: string): Promise<string>;
|
9
|
+
private base64Encode;
|
10
|
+
private base64Decode;
|
11
|
+
}
|
12
|
+
//# sourceMappingURL=encryption.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../../../../src/oauth/storage/encryption.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,MAAM,CAAkD;IAEnD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAqCrC,OAAO;YAMP,SAAS;IAWjB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IActC,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBrD,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,YAAY;CAUrB"}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
export class Encryptor {
|
2
|
+
key = null;
|
3
|
+
crypto = null;
|
4
|
+
async initialize(key) {
|
5
|
+
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
6
|
+
this.crypto = globalThis.crypto;
|
7
|
+
}
|
8
|
+
else if (typeof window !== "undefined" && window.crypto) {
|
9
|
+
this.crypto = window.crypto;
|
10
|
+
}
|
11
|
+
else {
|
12
|
+
try {
|
13
|
+
const nodeCrypto = await import("crypto");
|
14
|
+
this.crypto = nodeCrypto.webcrypto;
|
15
|
+
}
|
16
|
+
catch (error) {
|
17
|
+
throw new Error("Crypto API is not available in this environment. Cannot initialize encryption.");
|
18
|
+
}
|
19
|
+
}
|
20
|
+
if (!this.crypto) {
|
21
|
+
throw new Error("Crypto API initialization failed.");
|
22
|
+
}
|
23
|
+
if (!this.crypto.subtle) {
|
24
|
+
throw new Error("crypto.subtle is not available. Cannot perform encryption operations.");
|
25
|
+
}
|
26
|
+
if (!this.crypto.getRandomValues) {
|
27
|
+
throw new Error("crypto.getRandomValues is not available. Cannot generate secure random values for encryption.");
|
28
|
+
}
|
29
|
+
const encoder = new TextEncoder();
|
30
|
+
const hash = await this.hashKey(encoder.encode(key));
|
31
|
+
this.key = await this.importKey(hash);
|
32
|
+
}
|
33
|
+
async hashKey(keyData) {
|
34
|
+
if (!this.crypto)
|
35
|
+
throw new Error("Encryptor not initialized");
|
36
|
+
const hashBuffer = await this.crypto.subtle.digest("SHA-256", keyData);
|
37
|
+
return new Uint8Array(hashBuffer);
|
38
|
+
}
|
39
|
+
async importKey(keyData) {
|
40
|
+
if (!this.crypto)
|
41
|
+
throw new Error("Encryptor not initialized");
|
42
|
+
return this.crypto.subtle.importKey("raw", keyData, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
43
|
+
}
|
44
|
+
async encrypt(data) {
|
45
|
+
if (!this.key || !this.crypto)
|
46
|
+
throw new Error("Encryptor not initialized");
|
47
|
+
const iv = this.crypto.getRandomValues(new Uint8Array(12));
|
48
|
+
const encryptedData = await this.crypto.subtle.encrypt({ name: "AES-GCM", iv }, this.key, new TextEncoder().encode(data));
|
49
|
+
const combined = new Uint8Array([...iv, ...new Uint8Array(encryptedData)]);
|
50
|
+
return this.base64Encode(combined);
|
51
|
+
}
|
52
|
+
async decrypt(encryptedData) {
|
53
|
+
if (!this.key || !this.crypto)
|
54
|
+
throw new Error("Encryptor not initialized");
|
55
|
+
const combined = this.base64Decode(encryptedData);
|
56
|
+
const iv = combined.slice(0, 12);
|
57
|
+
const data = combined.slice(12);
|
58
|
+
const decrypted = await this.crypto.subtle.decrypt({ name: "AES-GCM", iv }, this.key, data);
|
59
|
+
return new TextDecoder().decode(decrypted);
|
60
|
+
}
|
61
|
+
base64Encode(buffer) {
|
62
|
+
if (typeof Buffer !== "undefined") {
|
63
|
+
return Buffer.from(buffer).toString("base64");
|
64
|
+
}
|
65
|
+
return btoa(String.fromCharCode(...buffer));
|
66
|
+
}
|
67
|
+
base64Decode(base64) {
|
68
|
+
if (typeof Buffer !== "undefined") {
|
69
|
+
return Buffer.from(base64, "base64");
|
70
|
+
}
|
71
|
+
return new Uint8Array(atob(base64)
|
72
|
+
.split("")
|
73
|
+
.map((c) => c.charCodeAt(0)));
|
74
|
+
}
|
75
|
+
}
|
76
|
+
//# sourceMappingURL=encryption.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../../../../src/oauth/storage/encryption.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;IACZ,GAAG,GAAqB,IAAI,CAAC;IAC7B,MAAM,GAA6C,IAAI,CAAC;IAEzD,KAAK,CAAC,UAAU,CAAC,GAAW;QACjC,IAAI,OAAO,UAAU,KAAK,WAAW,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YAC3D,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAClC,CAAC;aAAM,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,SAA8B,CAAC;YAC1D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,+FAA+F,CAChG,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,OAAmB;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,OAAqB;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACjC,KAAK,EACL,OAAO,EACP,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,KAAK,EACL,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAE5E,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CACpD,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EACvB,IAAI,CAAC,GAAG,EACR,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAC/B,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,aAAqB;QACjC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAE5E,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAEhC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAChD,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EACvB,IAAI,CAAC,GAAG,EACR,IAAI,CACL,CAAC;QAEF,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAEO,YAAY,CAAC,MAAkB;QACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAEO,YAAY,CAAC,MAAc;QACjC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,IAAI,UAAU,CACnB,IAAI,CAAC,MAAM,CAAC;aACT,KAAK,CAAC,EAAE,CAAC;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAC/B,CAAC;IACJ,CAAC;CACF"}
|