@adonisjs/ally 6.0.0-next.0 → 6.1.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 +2 -2
- package/build/{chunk-WM3V3APX.js → chunk-46TOMXWK.js} +92 -15
- package/build/chunk-6BP2DK5A.js +43 -0
- package/build/{chunk-KSJ4CFTC.js → chunk-NK6X76EQ.js} +16 -25
- package/build/{chunk-KWRXS6EG.js → chunk-SBQAXPUK.js} +33 -3
- package/build/chunk-TFPW7D75.js +125 -0
- package/build/index.js +67 -6
- package/build/providers/ally_provider.d.ts +10 -0
- package/build/providers/ally_provider.js +13 -2
- package/build/src/abstract_drivers/oauth1.d.ts +26 -0
- package/build/src/abstract_drivers/oauth2.d.ts +50 -2
- package/build/src/ally_manager.d.ts +67 -3
- package/build/src/debug.d.ts +1 -1
- package/build/src/define_config.d.ts +16 -1
- package/build/src/drivers/discord.d.ts +9 -0
- package/build/src/drivers/discord.js +13 -3
- package/build/src/drivers/facebook.d.ts +9 -0
- package/build/src/drivers/facebook.js +13 -3
- package/build/src/drivers/github.d.ts +12 -0
- package/build/src/drivers/github.js +17 -4
- package/build/src/drivers/google.d.ts +9 -0
- package/build/src/drivers/google.js +13 -3
- package/build/src/drivers/linked_in.d.ts +12 -0
- package/build/src/drivers/linked_in.js +16 -3
- package/build/src/drivers/linked_in_openid_connect.d.ts +14 -5
- package/build/src/drivers/linked_in_openid_connect.js +14 -5
- package/build/src/drivers/spotify.d.ts +11 -0
- package/build/src/drivers/spotify.js +15 -3
- package/build/src/drivers/twitter.d.ts +17 -0
- package/build/src/drivers/twitter.js +22 -3
- package/build/src/drivers/twitter_x.d.ts +137 -0
- package/build/src/drivers/twitter_x.js +169 -0
- package/build/src/errors.d.ts +29 -0
- package/build/src/redirect_request.d.ts +7 -0
- package/build/src/types.d.ts +150 -0
- package/package.json +27 -21
- package/build/chunk-MLKGABMK.js +0 -9
- package/build/chunk-SZ4YJCVU.js +0 -46
package/README.md
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url]
|
|
6
6
|
|
|
7
7
|
## Introduction
|
|
8
|
-
Social authentication provider for AdonisJS. Supports **Github**, **Google**, **Twitter**, **Facebook**, **Discord**, **Spotify**, and **LinkedIn**.
|
|
8
|
+
Social authentication provider for AdonisJS. Supports **Github**, **Google**, **Twitter**, **X (Twitter OAuth2)**, **Facebook**, **Discord**, **Spotify**, and **LinkedIn**.
|
|
9
9
|
|
|
10
10
|
## Official Documentation
|
|
11
|
-
The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/social-
|
|
11
|
+
The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/auth/social-authentication)
|
|
12
12
|
|
|
13
13
|
## Contributing
|
|
14
14
|
One of the primary goals of AdonisJS is to have a vibrant community of users and contributors who believes in the principles of the framework.
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
E_OAUTH_MISSING_CODE,
|
|
3
|
-
E_OAUTH_STATE_MISMATCH,
|
|
4
2
|
RedirectRequest
|
|
5
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NK6X76EQ.js";
|
|
4
|
+
import {
|
|
5
|
+
E_OAUTH_MISSING_CODE,
|
|
6
|
+
E_OAUTH_STATE_MISMATCH
|
|
7
|
+
} from "./chunk-6BP2DK5A.js";
|
|
6
8
|
|
|
7
9
|
// src/abstract_drivers/oauth2.ts
|
|
8
10
|
import { Exception } from "@adonisjs/core/exceptions";
|
|
9
11
|
import { Oauth2Client } from "@poppinss/oauth-client/oauth2";
|
|
10
12
|
var Oauth2Driver = class extends Oauth2Client {
|
|
11
13
|
/**
|
|
14
|
+
* Create a new OAuth2 driver instance.
|
|
15
|
+
*
|
|
12
16
|
* @param ctx - The current HTTP context
|
|
13
17
|
* @param config - OAuth2 driver configuration
|
|
14
18
|
*/
|
|
@@ -17,11 +21,18 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
17
21
|
this.ctx = ctx;
|
|
18
22
|
this.config = config;
|
|
19
23
|
}
|
|
24
|
+
ctx;
|
|
25
|
+
config;
|
|
20
26
|
/**
|
|
21
27
|
* Whether the authorization process is stateless. When true,
|
|
22
28
|
* state verification via cookies is disabled.
|
|
23
29
|
*/
|
|
24
30
|
isStateless = false;
|
|
31
|
+
/**
|
|
32
|
+
* The cookie name for storing the PKCE code verifier. Define this property
|
|
33
|
+
* in child classes that require PKCE.
|
|
34
|
+
*/
|
|
35
|
+
codeVerifierCookieName;
|
|
25
36
|
/**
|
|
26
37
|
* OAuth protocol version identifier
|
|
27
38
|
*/
|
|
@@ -30,19 +41,33 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
30
41
|
* Cached state value read from the cookie
|
|
31
42
|
*/
|
|
32
43
|
stateCookieValue;
|
|
44
|
+
/**
|
|
45
|
+
* Cached PKCE code verifier value read from the cookie via
|
|
46
|
+
* loadState
|
|
47
|
+
*/
|
|
48
|
+
codeVerifierCookieValue;
|
|
33
49
|
/**
|
|
34
50
|
* Creates a URL builder instance for constructing authorization URLs
|
|
35
51
|
* with scope support.
|
|
36
52
|
*
|
|
37
53
|
* @param url - The base authorization URL
|
|
54
|
+
* @returns A redirect request builder for the given URL.
|
|
38
55
|
*/
|
|
39
56
|
urlBuilder(url) {
|
|
40
57
|
return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator);
|
|
41
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Find if the driver uses PKCE for the OAuth2 authorization code flow.
|
|
61
|
+
*
|
|
62
|
+
* @returns `true` when the driver has PKCE enabled.
|
|
63
|
+
*/
|
|
64
|
+
#usesPkce() {
|
|
65
|
+
return !!this.codeVerifierCookieName;
|
|
66
|
+
}
|
|
42
67
|
/**
|
|
43
68
|
* Loads the state value from the encrypted cookie and immediately clears
|
|
44
|
-
* the cookie.
|
|
45
|
-
*
|
|
69
|
+
* the cookie. When PKCE is enabled, it also loads the PKCE code verifier.
|
|
70
|
+
* This must be called by child classes in their constructor.
|
|
46
71
|
*
|
|
47
72
|
* @example
|
|
48
73
|
* ```ts
|
|
@@ -58,25 +83,50 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
58
83
|
}
|
|
59
84
|
this.stateCookieValue = this.ctx.request.encryptedCookie(this.stateCookieName);
|
|
60
85
|
this.ctx.response.clearCookie(this.stateCookieName);
|
|
86
|
+
if (this.#usesPkce()) {
|
|
87
|
+
this.codeVerifierCookieValue = this.ctx.request.encryptedCookie(this.codeVerifierCookieName);
|
|
88
|
+
this.ctx.response.clearCookie(this.codeVerifierCookieName);
|
|
89
|
+
}
|
|
61
90
|
}
|
|
62
91
|
/**
|
|
63
|
-
*
|
|
92
|
+
* Returns the PKCE code verifier for building the authorization redirect.
|
|
93
|
+
* This method is expected to create and persist the verifier for later use.
|
|
94
|
+
*
|
|
95
|
+
* @returns The generated PKCE code verifier or `null` when PKCE is disabled.
|
|
64
96
|
*/
|
|
65
|
-
|
|
66
|
-
if (this
|
|
67
|
-
return;
|
|
97
|
+
getPkceCodeVerifierForRedirect() {
|
|
98
|
+
if (!this.#usesPkce()) {
|
|
99
|
+
return null;
|
|
68
100
|
}
|
|
69
|
-
const
|
|
70
|
-
this.ctx.response.encryptedCookie(this.
|
|
101
|
+
const codeVerifier = this.makeCodeVerifier();
|
|
102
|
+
this.ctx.response.encryptedCookie(this.codeVerifierCookieName, codeVerifier, {
|
|
71
103
|
sameSite: false,
|
|
72
104
|
httpOnly: true
|
|
73
105
|
});
|
|
74
|
-
|
|
106
|
+
this.codeVerifierCookieValue = codeVerifier;
|
|
107
|
+
return codeVerifier;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns the PKCE code verifier for the access token exchange.
|
|
111
|
+
* This method only reads the verifier that was persisted during redirect.
|
|
112
|
+
*
|
|
113
|
+
* @returns The persisted PKCE code verifier or `null` when PKCE is disabled.
|
|
114
|
+
*/
|
|
115
|
+
getPkceCodeVerifierForAccessToken() {
|
|
116
|
+
if (!this.#usesPkce()) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (!this.codeVerifierCookieValue) {
|
|
120
|
+
throw new E_OAUTH_MISSING_CODE(["code_verifier"]);
|
|
121
|
+
}
|
|
122
|
+
return this.codeVerifierCookieValue;
|
|
75
123
|
}
|
|
76
124
|
/**
|
|
77
125
|
* Enable stateless authentication by disabling CSRF state verification.
|
|
78
126
|
* Only use this in scenarios where state verification is not required.
|
|
79
127
|
*
|
|
128
|
+
* @returns The current driver instance.
|
|
129
|
+
*
|
|
80
130
|
* @example
|
|
81
131
|
* ```ts
|
|
82
132
|
* await ally.use('github').stateless().redirect()
|
|
@@ -92,6 +142,7 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
92
142
|
* in a different context.
|
|
93
143
|
*
|
|
94
144
|
* @param callback - Optional callback to customize the redirect request
|
|
145
|
+
* @returns A promise resolving to the authorization URL.
|
|
95
146
|
*
|
|
96
147
|
* @example
|
|
97
148
|
* ```ts
|
|
@@ -109,6 +160,7 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
109
160
|
* The state parameter is automatically set for CSRF protection.
|
|
110
161
|
*
|
|
111
162
|
* @param callback - Optional callback to customize the redirect request
|
|
163
|
+
* @returns A promise that resolves after the redirect response is prepared.
|
|
112
164
|
*
|
|
113
165
|
* @example
|
|
114
166
|
* ```ts
|
|
@@ -120,8 +172,14 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
120
172
|
*/
|
|
121
173
|
async redirect(callback) {
|
|
122
174
|
const url = await this.redirectUrl((request) => {
|
|
123
|
-
|
|
124
|
-
|
|
175
|
+
if (!this.isStateless) {
|
|
176
|
+
const state = this.getState();
|
|
177
|
+
this.ctx.response.encryptedCookie(this.stateCookieName, state, {
|
|
178
|
+
sameSite: false,
|
|
179
|
+
httpOnly: true
|
|
180
|
+
});
|
|
181
|
+
request.param(this.stateParamName, state);
|
|
182
|
+
}
|
|
125
183
|
if (typeof callback === "function") {
|
|
126
184
|
callback(request);
|
|
127
185
|
}
|
|
@@ -131,15 +189,25 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
131
189
|
/**
|
|
132
190
|
* Check if the state parameter from the callback matches the state
|
|
133
191
|
* stored in the cookie. Returns false in stateless mode.
|
|
192
|
+
*
|
|
193
|
+
* @returns `true` when the state validation fails.
|
|
134
194
|
*/
|
|
135
195
|
stateMisMatch() {
|
|
136
196
|
if (this.isStateless) {
|
|
137
197
|
return false;
|
|
138
198
|
}
|
|
139
|
-
|
|
199
|
+
if (this.stateCookieValue !== this.ctx.request.input(this.stateParamName)) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
if (this.#usesPkce() && !this.codeVerifierCookieValue) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
140
206
|
}
|
|
141
207
|
/**
|
|
142
208
|
* Check if an error was returned by the OAuth provider.
|
|
209
|
+
*
|
|
210
|
+
* @returns `true` when an error exists on the callback request.
|
|
143
211
|
*/
|
|
144
212
|
hasError() {
|
|
145
213
|
return !!this.getError();
|
|
@@ -147,6 +215,8 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
147
215
|
/**
|
|
148
216
|
* Get the error code or message returned by the OAuth provider.
|
|
149
217
|
* Returns 'unknown_error' if no code is present and no error was specified.
|
|
218
|
+
*
|
|
219
|
+
* @returns The provider error value when present.
|
|
150
220
|
*/
|
|
151
221
|
getError() {
|
|
152
222
|
const error = this.ctx.request.input(this.errorParamName);
|
|
@@ -160,12 +230,16 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
160
230
|
}
|
|
161
231
|
/**
|
|
162
232
|
* Get the authorization code from the callback request.
|
|
233
|
+
*
|
|
234
|
+
* @returns The authorization code when present.
|
|
163
235
|
*/
|
|
164
236
|
getCode() {
|
|
165
237
|
return this.ctx.request.input(this.codeParamName, null);
|
|
166
238
|
}
|
|
167
239
|
/**
|
|
168
240
|
* Check if the authorization code is present in the callback request.
|
|
241
|
+
*
|
|
242
|
+
* @returns `true` when the callback request contains an authorization code.
|
|
169
243
|
*/
|
|
170
244
|
hasCode() {
|
|
171
245
|
return !!this.getCode();
|
|
@@ -175,6 +249,7 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
175
249
|
* validates the state and checks for errors before making the request.
|
|
176
250
|
*
|
|
177
251
|
* @param callback - Optional callback to customize the token request
|
|
252
|
+
* @returns A promise resolving to the access token payload.
|
|
178
253
|
*
|
|
179
254
|
* @example
|
|
180
255
|
* ```ts
|
|
@@ -197,6 +272,8 @@ var Oauth2Driver = class extends Oauth2Client {
|
|
|
197
272
|
}
|
|
198
273
|
/**
|
|
199
274
|
* Not applicable with OAuth2. Use `userFromToken` instead.
|
|
275
|
+
*
|
|
276
|
+
* @returns This method never returns.
|
|
200
277
|
*/
|
|
201
278
|
async userFromTokenAndSecret() {
|
|
202
279
|
throw new Exception(
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/errors.ts
|
|
8
|
+
var errors_exports = {};
|
|
9
|
+
__export(errors_exports, {
|
|
10
|
+
E_LOCAL_SIGNUP_DISALLOWED: () => E_LOCAL_SIGNUP_DISALLOWED,
|
|
11
|
+
E_OAUTH_MISSING_CODE: () => E_OAUTH_MISSING_CODE,
|
|
12
|
+
E_OAUTH_STATE_MISMATCH: () => E_OAUTH_STATE_MISMATCH,
|
|
13
|
+
E_UNKNOWN_ALLY_PROVIDER: () => E_UNKNOWN_ALLY_PROVIDER
|
|
14
|
+
});
|
|
15
|
+
import { createError } from "@adonisjs/core/exceptions";
|
|
16
|
+
var E_OAUTH_MISSING_CODE = createError(
|
|
17
|
+
'Cannot request access token. Redirect request is missing the "%s" param',
|
|
18
|
+
"E_OAUTH_MISSING_CODE",
|
|
19
|
+
500
|
|
20
|
+
);
|
|
21
|
+
var E_OAUTH_STATE_MISMATCH = createError(
|
|
22
|
+
"Unable to verify re-redirect state",
|
|
23
|
+
"E_OAUTH_STATE_MISMATCH",
|
|
24
|
+
400
|
|
25
|
+
);
|
|
26
|
+
var E_UNKNOWN_ALLY_PROVIDER = createError(
|
|
27
|
+
'Unknown ally provider "%s". Make sure it is registered inside the config/ally.ts file',
|
|
28
|
+
"E_UNKNOWN_ALLY_PROVIDER",
|
|
29
|
+
404
|
|
30
|
+
);
|
|
31
|
+
var E_LOCAL_SIGNUP_DISALLOWED = createError(
|
|
32
|
+
'Cannot use ally provider "%s" for signup. Local signup is disabled for this provider',
|
|
33
|
+
"E_LOCAL_SIGNUP_DISALLOWED",
|
|
34
|
+
403
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
E_OAUTH_MISSING_CODE,
|
|
39
|
+
E_OAUTH_STATE_MISMATCH,
|
|
40
|
+
E_UNKNOWN_ALLY_PROVIDER,
|
|
41
|
+
E_LOCAL_SIGNUP_DISALLOWED,
|
|
42
|
+
errors_exports
|
|
43
|
+
};
|
|
@@ -1,32 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__export
|
|
3
|
-
} from "./chunk-MLKGABMK.js";
|
|
4
|
-
|
|
5
|
-
// src/errors.ts
|
|
6
|
-
var errors_exports = {};
|
|
7
|
-
__export(errors_exports, {
|
|
8
|
-
E_OAUTH_MISSING_CODE: () => E_OAUTH_MISSING_CODE,
|
|
9
|
-
E_OAUTH_STATE_MISMATCH: () => E_OAUTH_STATE_MISMATCH
|
|
10
|
-
});
|
|
11
|
-
import { createError } from "@adonisjs/core/exceptions";
|
|
12
|
-
var E_OAUTH_MISSING_CODE = createError(
|
|
13
|
-
'Cannot request access token. Redirect request is missing the "%s" param',
|
|
14
|
-
"E_OAUTH_MISSING_CODE",
|
|
15
|
-
500
|
|
16
|
-
);
|
|
17
|
-
var E_OAUTH_STATE_MISMATCH = createError(
|
|
18
|
-
"Unable to verify re-redirect state",
|
|
19
|
-
"E_OAUTH_STATE_MISMATCH",
|
|
20
|
-
400
|
|
21
|
-
);
|
|
22
|
-
|
|
23
1
|
// src/redirect_request.ts
|
|
24
2
|
import { UrlBuilder } from "@poppinss/oauth-client";
|
|
25
3
|
var RedirectRequest = class extends UrlBuilder {
|
|
4
|
+
/**
|
|
5
|
+
* Optional callback used to transform scope values before serialization.
|
|
6
|
+
*/
|
|
26
7
|
#scopesTransformer;
|
|
8
|
+
/**
|
|
9
|
+
* Query parameter name used to serialize the scope string.
|
|
10
|
+
*/
|
|
27
11
|
#scopeParamName;
|
|
12
|
+
/**
|
|
13
|
+
* Separator used when joining multiple scopes.
|
|
14
|
+
*/
|
|
28
15
|
#scopeSeparator;
|
|
29
16
|
/**
|
|
17
|
+
* Create a redirect request builder with scope helpers.
|
|
18
|
+
*
|
|
30
19
|
* @param baseUrl - The authorization URL for the OAuth provider
|
|
31
20
|
* @param scopeParamName - The query parameter name for scopes (e.g., 'scope')
|
|
32
21
|
* @param scopeSeparator - The character used to separate multiple scopes (e.g., ' ' or ',')
|
|
@@ -42,6 +31,7 @@ var RedirectRequest = class extends UrlBuilder {
|
|
|
42
31
|
* require scope prefixes or transformations.
|
|
43
32
|
*
|
|
44
33
|
* @param callback - Function that transforms the scopes array
|
|
34
|
+
* @returns The current redirect request instance.
|
|
45
35
|
*
|
|
46
36
|
* @example
|
|
47
37
|
* ```ts
|
|
@@ -59,6 +49,7 @@ var RedirectRequest = class extends UrlBuilder {
|
|
|
59
49
|
* any previously set scopes.
|
|
60
50
|
*
|
|
61
51
|
* @param scopes - Array of scope strings to request
|
|
52
|
+
* @returns The current redirect request instance.
|
|
62
53
|
*
|
|
63
54
|
* @example
|
|
64
55
|
* ```ts
|
|
@@ -77,6 +68,7 @@ var RedirectRequest = class extends UrlBuilder {
|
|
|
77
68
|
* for adding scopes without replacing the default ones.
|
|
78
69
|
*
|
|
79
70
|
* @param scopes - Array of scope strings to merge
|
|
71
|
+
* @returns The current redirect request instance.
|
|
80
72
|
*
|
|
81
73
|
* @example
|
|
82
74
|
* ```ts
|
|
@@ -101,6 +93,8 @@ var RedirectRequest = class extends UrlBuilder {
|
|
|
101
93
|
/**
|
|
102
94
|
* Clear all existing scopes from the authorization request.
|
|
103
95
|
*
|
|
96
|
+
* @returns The current redirect request instance.
|
|
97
|
+
*
|
|
104
98
|
* @example
|
|
105
99
|
* ```ts
|
|
106
100
|
* request.clearScopes().scopes(['user'])
|
|
@@ -113,8 +107,5 @@ var RedirectRequest = class extends UrlBuilder {
|
|
|
113
107
|
};
|
|
114
108
|
|
|
115
109
|
export {
|
|
116
|
-
E_OAUTH_MISSING_CODE,
|
|
117
|
-
E_OAUTH_STATE_MISMATCH,
|
|
118
|
-
errors_exports,
|
|
119
110
|
RedirectRequest
|
|
120
111
|
};
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
E_OAUTH_MISSING_CODE,
|
|
3
|
-
E_OAUTH_STATE_MISMATCH,
|
|
4
2
|
RedirectRequest
|
|
5
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NK6X76EQ.js";
|
|
4
|
+
import {
|
|
5
|
+
E_OAUTH_MISSING_CODE,
|
|
6
|
+
E_OAUTH_STATE_MISMATCH
|
|
7
|
+
} from "./chunk-6BP2DK5A.js";
|
|
6
8
|
|
|
7
9
|
// src/abstract_drivers/oauth1.ts
|
|
8
10
|
import { Exception } from "@adonisjs/core/exceptions";
|
|
9
11
|
import { Oauth1Client } from "@poppinss/oauth-client/oauth1";
|
|
10
12
|
var Oauth1Driver = class extends Oauth1Client {
|
|
11
13
|
/**
|
|
14
|
+
* Create a new OAuth1 driver instance.
|
|
15
|
+
*
|
|
12
16
|
* @param ctx - The current HTTP context
|
|
13
17
|
* @param config - OAuth1 driver configuration
|
|
14
18
|
*/
|
|
@@ -17,6 +21,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
17
21
|
this.ctx = ctx;
|
|
18
22
|
this.config = config;
|
|
19
23
|
}
|
|
24
|
+
ctx;
|
|
25
|
+
config;
|
|
20
26
|
/**
|
|
21
27
|
* OAuth protocol version identifier
|
|
22
28
|
*/
|
|
@@ -29,6 +35,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
29
35
|
/**
|
|
30
36
|
* The cookie name for storing the OAuth token secret.
|
|
31
37
|
* Automatically derived from the token cookie name.
|
|
38
|
+
*
|
|
39
|
+
* @returns The cookie name used to persist the OAuth token secret.
|
|
32
40
|
*/
|
|
33
41
|
get oauthSecretCookieName() {
|
|
34
42
|
return `${this.oauthTokenCookieName}_secret`;
|
|
@@ -38,6 +46,7 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
38
46
|
* with scope support.
|
|
39
47
|
*
|
|
40
48
|
* @param url - The base authorization URL
|
|
49
|
+
* @returns A redirect request builder for the given URL.
|
|
41
50
|
*/
|
|
42
51
|
urlBuilder(url) {
|
|
43
52
|
return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator);
|
|
@@ -63,6 +72,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
63
72
|
}
|
|
64
73
|
/**
|
|
65
74
|
* Stores the OAuth token in an encrypted cookie for later use
|
|
75
|
+
*
|
|
76
|
+
* @param token - The request token to persist.
|
|
66
77
|
*/
|
|
67
78
|
#persistToken(token) {
|
|
68
79
|
this.ctx.response.encryptedCookie(this.oauthTokenCookieName, token, {
|
|
@@ -72,6 +83,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
72
83
|
}
|
|
73
84
|
/**
|
|
74
85
|
* Stores the OAuth token secret in an encrypted cookie for later use
|
|
86
|
+
*
|
|
87
|
+
* @param secret - The request token secret to persist.
|
|
75
88
|
*/
|
|
76
89
|
#persistSecret(secret) {
|
|
77
90
|
this.ctx.response.encryptedCookie(this.oauthSecretCookieName, secret, {
|
|
@@ -82,6 +95,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
82
95
|
/**
|
|
83
96
|
* OAuth1 does not support stateless authentication due to the
|
|
84
97
|
* three-legged authentication flow requiring token persistence.
|
|
98
|
+
*
|
|
99
|
+
* @returns This method never returns.
|
|
85
100
|
*/
|
|
86
101
|
stateless() {
|
|
87
102
|
throw new Exception("OAuth1 does not support stateless authorization");
|
|
@@ -92,6 +107,7 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
92
107
|
* in a different context.
|
|
93
108
|
*
|
|
94
109
|
* @param callback - Optional callback to customize the redirect request
|
|
110
|
+
* @returns A promise resolving to the authorization URL.
|
|
95
111
|
*
|
|
96
112
|
* @example
|
|
97
113
|
* ```ts
|
|
@@ -106,6 +122,7 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
106
122
|
* The request token is automatically obtained and stored in cookies.
|
|
107
123
|
*
|
|
108
124
|
* @param callback - Optional callback to customize the redirect request
|
|
125
|
+
* @returns A promise that resolves after the redirect response is prepared.
|
|
109
126
|
*
|
|
110
127
|
* @example
|
|
111
128
|
* ```ts
|
|
@@ -127,12 +144,16 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
127
144
|
/**
|
|
128
145
|
* Check if the OAuth token from the callback matches the token
|
|
129
146
|
* stored in the cookie.
|
|
147
|
+
*
|
|
148
|
+
* @returns `true` when the callback token does not match the stored token.
|
|
130
149
|
*/
|
|
131
150
|
stateMisMatch() {
|
|
132
151
|
return this.oauthTokenCookieValue !== this.ctx.request.input(this.oauthTokenParamName);
|
|
133
152
|
}
|
|
134
153
|
/**
|
|
135
154
|
* Check if an error was returned by the OAuth provider.
|
|
155
|
+
*
|
|
156
|
+
* @returns `true` when an error exists on the callback request.
|
|
136
157
|
*/
|
|
137
158
|
hasError() {
|
|
138
159
|
return !!this.getError();
|
|
@@ -140,6 +161,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
140
161
|
/**
|
|
141
162
|
* Get the error code or message returned by the OAuth provider.
|
|
142
163
|
* Returns 'unknown_error' if no verifier is present and no error was specified.
|
|
164
|
+
*
|
|
165
|
+
* @returns The provider error value when present.
|
|
143
166
|
*/
|
|
144
167
|
getError() {
|
|
145
168
|
const error = this.ctx.request.input(this.errorParamName);
|
|
@@ -153,12 +176,16 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
153
176
|
}
|
|
154
177
|
/**
|
|
155
178
|
* Get the OAuth verifier from the callback request.
|
|
179
|
+
*
|
|
180
|
+
* @returns The OAuth verifier when present.
|
|
156
181
|
*/
|
|
157
182
|
getCode() {
|
|
158
183
|
return this.ctx.request.input(this.oauthTokenVerifierName, null);
|
|
159
184
|
}
|
|
160
185
|
/**
|
|
161
186
|
* Check if the OAuth verifier is present in the callback request.
|
|
187
|
+
*
|
|
188
|
+
* @returns `true` when the callback request contains an OAuth verifier.
|
|
162
189
|
*/
|
|
163
190
|
hasCode() {
|
|
164
191
|
return !!this.getCode();
|
|
@@ -169,6 +196,7 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
169
196
|
* making the request.
|
|
170
197
|
*
|
|
171
198
|
* @param callback - Optional callback to customize the token request
|
|
199
|
+
* @returns A promise resolving to the access token payload.
|
|
172
200
|
*
|
|
173
201
|
* @example
|
|
174
202
|
* ```ts
|
|
@@ -194,6 +222,8 @@ var Oauth1Driver = class extends Oauth1Client {
|
|
|
194
222
|
}
|
|
195
223
|
/**
|
|
196
224
|
* Not applicable with OAuth1. Use `userFromTokenAndSecret` instead.
|
|
225
|
+
*
|
|
226
|
+
* @returns This method never returns.
|
|
197
227
|
*/
|
|
198
228
|
async userFromToken() {
|
|
199
229
|
throw new Exception(
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
E_LOCAL_SIGNUP_DISALLOWED,
|
|
3
|
+
E_UNKNOWN_ALLY_PROVIDER
|
|
4
|
+
} from "./chunk-6BP2DK5A.js";
|
|
5
|
+
|
|
6
|
+
// src/ally_manager.ts
|
|
7
|
+
var AllyManager = class {
|
|
8
|
+
/**
|
|
9
|
+
* Create a new Ally manager for the current request.
|
|
10
|
+
*
|
|
11
|
+
* @param config - Map of provider names to driver factory functions
|
|
12
|
+
* @param ctx - The current HTTP context
|
|
13
|
+
*/
|
|
14
|
+
constructor(config, ctx) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.#ctx = ctx;
|
|
17
|
+
}
|
|
18
|
+
config;
|
|
19
|
+
/**
|
|
20
|
+
* The current HTTP context bound to this manager instance.
|
|
21
|
+
*/
|
|
22
|
+
#ctx;
|
|
23
|
+
/**
|
|
24
|
+
* Cache of instantiated providers keyed by provider name.
|
|
25
|
+
*/
|
|
26
|
+
#driversCache = /* @__PURE__ */ new Map();
|
|
27
|
+
/**
|
|
28
|
+
* Find if a provider has been configured.
|
|
29
|
+
*
|
|
30
|
+
* @param provider - The provider name to check.
|
|
31
|
+
* @returns `true` when the provider exists in the manager config.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* if (ally.has(provider)) {
|
|
36
|
+
* await ally.use(provider).redirect()
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
has(provider) {
|
|
41
|
+
return provider in this.config;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find if a provider allows local signup.
|
|
45
|
+
*
|
|
46
|
+
* @param provider - The configured provider name to inspect.
|
|
47
|
+
* @returns `true` when the provider does not opt out of local signup.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* if (ally.allowsLocalSignup('github')) {
|
|
52
|
+
* return ally.use('github', { intent: 'signup' }).redirect()
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
allowsLocalSignup(provider) {
|
|
57
|
+
if (!this.has(provider)) {
|
|
58
|
+
throw new E_UNKNOWN_ALLY_PROVIDER([provider]);
|
|
59
|
+
}
|
|
60
|
+
const driver = this.use(provider);
|
|
61
|
+
return !driver.config?.disallowLocalSignup;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns configured provider names.
|
|
65
|
+
*
|
|
66
|
+
* @returns An array of configured provider names.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const providers = ally.configuredProviderNames()
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
configuredProviderNames() {
|
|
74
|
+
return Object.keys(this.config);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns provider names that allow local signup.
|
|
78
|
+
*
|
|
79
|
+
* @returns An array of configured provider names that allow signup flows.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* const signupProviders = ally.signupProviderNames()
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
signupProviderNames() {
|
|
87
|
+
return this.configuredProviderNames().filter((provider) => this.allowsLocalSignup(provider));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get a driver instance for the specified social provider. The driver
|
|
91
|
+
* instance is cached for the duration of the HTTP request.
|
|
92
|
+
*
|
|
93
|
+
* @param provider - The name of the social provider (e.g., 'github', 'google')
|
|
94
|
+
* @param options - Additional options used to qualify the provider usage.
|
|
95
|
+
* @returns The instantiated social authentication driver.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* const github = ally.use('github')
|
|
100
|
+
* await github.redirect()
|
|
101
|
+
*
|
|
102
|
+
* const signupDriver = ally.use('github', { intent: 'signup' })
|
|
103
|
+
* await signupDriver.redirect()
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
use(provider, options) {
|
|
107
|
+
if (this.#driversCache.has(provider)) {
|
|
108
|
+
return this.#driversCache.get(provider);
|
|
109
|
+
}
|
|
110
|
+
if (!this.has(String(provider))) {
|
|
111
|
+
throw new E_UNKNOWN_ALLY_PROVIDER([provider]);
|
|
112
|
+
}
|
|
113
|
+
const driver = this.config[provider];
|
|
114
|
+
if (options?.intent === "signup" && !this.allowsLocalSignup(provider)) {
|
|
115
|
+
throw new E_LOCAL_SIGNUP_DISALLOWED([provider]);
|
|
116
|
+
}
|
|
117
|
+
const driverInstance = driver(this.#ctx);
|
|
118
|
+
this.#driversCache.set(provider, driverInstance);
|
|
119
|
+
return driverInstance;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
AllyManager
|
|
125
|
+
};
|