binoauth 0.0.11 → 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.
Files changed (111) hide show
  1. package/README.md +359 -165
  2. package/dist/core/src/admin/client.d.ts +203 -0
  3. package/dist/core/src/admin/client.d.ts.map +1 -0
  4. package/dist/core/src/admin/client.js +391 -0
  5. package/dist/core/src/admin/client.js.map +1 -0
  6. package/dist/core/src/admin/index.d.ts +6 -0
  7. package/dist/core/src/admin/index.d.ts.map +1 -0
  8. package/dist/core/src/admin/index.js +5 -0
  9. package/dist/core/src/admin/index.js.map +1 -0
  10. package/dist/core/src/admin/types.d.ts +412 -0
  11. package/dist/core/src/admin/types.d.ts.map +1 -0
  12. package/dist/core/src/admin/types.js +5 -0
  13. package/dist/core/src/admin/types.js.map +1 -0
  14. package/dist/core/src/auth/client.d.ts +330 -0
  15. package/dist/core/src/auth/client.d.ts.map +1 -0
  16. package/dist/core/src/auth/client.js +408 -0
  17. package/dist/core/src/auth/client.js.map +1 -0
  18. package/dist/core/src/auth/error.d.ts +113 -0
  19. package/dist/core/src/auth/error.d.ts.map +1 -0
  20. package/dist/core/src/auth/error.js +257 -0
  21. package/dist/core/src/auth/error.js.map +1 -0
  22. package/dist/core/src/auth/flows/base-flow.d.ts +98 -0
  23. package/dist/core/src/auth/flows/base-flow.d.ts.map +1 -0
  24. package/dist/core/src/auth/flows/base-flow.js +182 -0
  25. package/dist/core/src/auth/flows/base-flow.js.map +1 -0
  26. package/dist/core/src/auth/flows/magic-link.d.ts +175 -0
  27. package/dist/core/src/auth/flows/magic-link.d.ts.map +1 -0
  28. package/dist/core/src/auth/flows/magic-link.js +228 -0
  29. package/dist/core/src/auth/flows/magic-link.js.map +1 -0
  30. package/dist/core/src/auth/flows/mfa.d.ts +81 -0
  31. package/dist/core/src/auth/flows/mfa.d.ts.map +1 -0
  32. package/dist/core/src/auth/flows/mfa.js +103 -0
  33. package/dist/core/src/auth/flows/mfa.js.map +1 -0
  34. package/dist/core/src/auth/flows/otp.d.ts +172 -0
  35. package/dist/core/src/auth/flows/otp.d.ts.map +1 -0
  36. package/dist/core/src/auth/flows/otp.js +222 -0
  37. package/dist/core/src/auth/flows/otp.js.map +1 -0
  38. package/dist/core/src/auth/flows/password.d.ts +242 -0
  39. package/dist/core/src/auth/flows/password.d.ts.map +1 -0
  40. package/dist/core/src/auth/flows/password.js +344 -0
  41. package/dist/core/src/auth/flows/password.js.map +1 -0
  42. package/dist/core/src/auth/flows/social.d.ts +209 -0
  43. package/dist/core/src/auth/flows/social.d.ts.map +1 -0
  44. package/dist/core/src/auth/flows/social.js +284 -0
  45. package/dist/core/src/auth/flows/social.js.map +1 -0
  46. package/dist/core/src/auth/index.d.ts +19 -0
  47. package/dist/core/src/auth/index.d.ts.map +1 -0
  48. package/dist/core/src/auth/index.js +32 -0
  49. package/dist/core/src/auth/index.js.map +1 -0
  50. package/dist/core/src/auth/types.d.ts +151 -0
  51. package/dist/core/src/auth/types.d.ts.map +1 -0
  52. package/dist/core/src/auth/types.js +7 -0
  53. package/dist/core/src/auth/types.js.map +1 -0
  54. package/dist/core/src/index.d.ts +53 -49
  55. package/dist/core/src/index.d.ts.map +1 -1
  56. package/dist/core/src/index.js +61 -343
  57. package/dist/core/src/index.js.map +1 -1
  58. package/dist/core/src/oauth/client.d.ts +322 -0
  59. package/dist/core/src/oauth/client.d.ts.map +1 -0
  60. package/dist/core/src/oauth/client.js +491 -0
  61. package/dist/core/src/oauth/client.js.map +1 -0
  62. package/dist/core/src/oauth/error.d.ts +18 -0
  63. package/dist/core/src/oauth/error.d.ts.map +1 -0
  64. package/dist/core/src/oauth/error.js +24 -0
  65. package/dist/core/src/oauth/error.js.map +1 -0
  66. package/dist/core/src/oauth/flows/authorization-code.d.ts +122 -0
  67. package/dist/core/src/oauth/flows/authorization-code.d.ts.map +1 -0
  68. package/dist/core/src/oauth/flows/authorization-code.js +278 -0
  69. package/dist/core/src/oauth/flows/authorization-code.js.map +1 -0
  70. package/dist/core/src/oauth/flows/base-flow.d.ts +17 -0
  71. package/dist/core/src/oauth/flows/base-flow.d.ts.map +1 -0
  72. package/dist/core/src/oauth/flows/base-flow.js +107 -0
  73. package/dist/core/src/oauth/flows/base-flow.js.map +1 -0
  74. package/dist/core/src/oauth/flows/client-credentials.d.ts +72 -0
  75. package/dist/core/src/oauth/flows/client-credentials.d.ts.map +1 -0
  76. package/dist/core/src/oauth/flows/client-credentials.js +100 -0
  77. package/dist/core/src/oauth/flows/client-credentials.js.map +1 -0
  78. package/dist/core/src/oauth/flows/device-code.d.ts +108 -0
  79. package/dist/core/src/oauth/flows/device-code.d.ts.map +1 -0
  80. package/dist/core/src/oauth/flows/device-code.js +193 -0
  81. package/dist/core/src/oauth/flows/device-code.js.map +1 -0
  82. package/dist/core/src/oauth/flows/refresh-token.d.ts +59 -0
  83. package/dist/core/src/oauth/flows/refresh-token.d.ts.map +1 -0
  84. package/dist/core/src/oauth/flows/refresh-token.js +105 -0
  85. package/dist/core/src/oauth/flows/refresh-token.js.map +1 -0
  86. package/dist/core/src/oauth/index.d.ts +12 -0
  87. package/dist/core/src/oauth/index.d.ts.map +1 -0
  88. package/dist/core/src/oauth/index.js +11 -0
  89. package/dist/core/src/oauth/index.js.map +1 -0
  90. package/dist/core/src/oauth/storage/encryption.d.ts +12 -0
  91. package/dist/core/src/oauth/storage/encryption.d.ts.map +1 -0
  92. package/dist/core/src/oauth/storage/encryption.js +76 -0
  93. package/dist/core/src/oauth/storage/encryption.js.map +1 -0
  94. package/dist/core/src/oauth/storage/index.d.ts +201 -0
  95. package/dist/core/src/oauth/storage/index.d.ts.map +1 -0
  96. package/dist/core/src/oauth/storage/index.js +322 -0
  97. package/dist/core/src/oauth/storage/index.js.map +1 -0
  98. package/dist/core/src/oauth/storage/strategies.d.ts +34 -0
  99. package/dist/core/src/oauth/storage/strategies.d.ts.map +1 -0
  100. package/dist/core/src/oauth/storage/strategies.js +100 -0
  101. package/dist/core/src/oauth/storage/strategies.js.map +1 -0
  102. package/dist/core/src/oauth/types.d.ts +261 -0
  103. package/dist/core/src/oauth/types.d.ts.map +1 -0
  104. package/dist/core/src/oauth/types.js +39 -0
  105. package/dist/core/src/oauth/types.js.map +1 -0
  106. package/dist/core/src/oauth/utils.d.ts +56 -0
  107. package/dist/core/src/oauth/utils.d.ts.map +1 -0
  108. package/dist/core/src/oauth/utils.js +140 -0
  109. package/dist/core/src/oauth/utils.js.map +1 -0
  110. package/dist/tsconfig.tsbuildinfo +1 -1
  111. 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":"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"}