@adonisjs/ally 5.1.0 → 6.0.0-next.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/build/{chunk-N72DEJC2.js → chunk-KSJ4CFTC.js} +45 -8
- package/build/{chunk-VHORNQLN.js → chunk-KWRXS6EG.js} +65 -28
- package/build/{chunk-PZ5AY32C.js → chunk-MLKGABMK.js} +0 -1
- package/build/{chunk-NZT2DLWM.js → chunk-SZ4YJCVU.js} +15 -3
- package/build/chunk-WM3V3APX.js +210 -0
- package/build/index.d.ts +8 -8
- package/build/index.js +6 -8
- package/build/providers/ally_provider.d.ts +1 -1
- package/build/providers/ally_provider.js +3 -4
- package/build/src/abstract_drivers/oauth1.d.ts +115 -49
- package/build/src/abstract_drivers/oauth2.d.ts +121 -50
- package/build/src/ally_manager.d.ts +31 -4
- package/build/src/debug.d.ts +9 -0
- package/build/src/define_config.d.ts +45 -11
- package/build/src/drivers/discord.d.ts +76 -11
- package/build/src/drivers/discord.js +47 -12
- package/build/src/drivers/facebook.d.ts +73 -10
- package/build/src/drivers/facebook.js +44 -11
- package/build/src/drivers/github.d.ts +85 -13
- package/build/src/drivers/github.js +56 -14
- package/build/src/drivers/google.d.ts +80 -11
- package/build/src/drivers/google.js +50 -12
- package/build/src/drivers/linked_in.d.ts +76 -10
- package/build/src/drivers/linked_in.js +47 -12
- package/build/src/drivers/linked_in_openid_connect.d.ts +72 -9
- package/build/src/drivers/linked_in_openid_connect.js +42 -10
- package/build/src/drivers/spotify.d.ts +73 -10
- package/build/src/drivers/spotify.js +44 -11
- package/build/src/drivers/twitter.d.ts +65 -8
- package/build/src/drivers/twitter.js +37 -9
- package/build/src/errors.d.ts +10 -2
- package/build/src/redirect_request.d.ts +47 -7
- package/build/src/types.d.ts +1 -1
- package/build/src/types.js +0 -1
- package/package.json +57 -68
- package/build/chunk-GWAQFMNS.js +0 -164
- package/build/chunk-GWAQFMNS.js.map +0 -1
- package/build/chunk-N72DEJC2.js.map +0 -1
- package/build/chunk-NZT2DLWM.js.map +0 -1
- package/build/chunk-PZ5AY32C.js.map +0 -1
- package/build/chunk-VHORNQLN.js.map +0 -1
- package/build/index.js.map +0 -1
- package/build/providers/ally_provider.js.map +0 -1
- package/build/src/drivers/discord.js.map +0 -1
- package/build/src/drivers/facebook.js.map +0 -1
- package/build/src/drivers/github.js.map +0 -1
- package/build/src/drivers/google.js.map +0 -1
- package/build/src/drivers/linked_in.js.map +0 -1
- package/build/src/drivers/linked_in_openid_connect.js.map +0 -1
- package/build/src/drivers/spotify.js.map +0 -1
- package/build/src/drivers/twitter.js.map +0 -1
- package/build/src/types.js.map +0 -1
|
@@ -1,26 +1,66 @@
|
|
|
1
1
|
import { UrlBuilder } from '@poppinss/oauth-client';
|
|
2
|
-
import { LiteralStringUnion } from './types.
|
|
2
|
+
import { type LiteralStringUnion } from './types.ts';
|
|
3
3
|
/**
|
|
4
|
-
* Redirect request with first
|
|
4
|
+
* Redirect request with first-class support for defining OAuth scopes.
|
|
5
|
+
* Extends the UrlBuilder from the OAuth client to provide scope management
|
|
6
|
+
* capabilities specific to social authentication providers.
|
|
5
7
|
*/
|
|
6
8
|
export declare class RedirectRequest<Scopes extends string> extends UrlBuilder {
|
|
7
9
|
#private;
|
|
10
|
+
/**
|
|
11
|
+
* @param baseUrl - The authorization URL for the OAuth provider
|
|
12
|
+
* @param scopeParamName - The query parameter name for scopes (e.g., 'scope')
|
|
13
|
+
* @param scopeSeparator - The character used to separate multiple scopes (e.g., ' ' or ',')
|
|
14
|
+
*/
|
|
8
15
|
constructor(baseUrl: string, scopeParamName: string, scopeSeparator: string);
|
|
9
16
|
/**
|
|
10
|
-
* Register a custom function to transform scopes
|
|
11
|
-
* to
|
|
17
|
+
* Register a custom function to transform scopes before they are
|
|
18
|
+
* added to the authorization URL. This is useful for providers that
|
|
19
|
+
* require scope prefixes or transformations.
|
|
20
|
+
*
|
|
21
|
+
* @param callback - Function that transforms the scopes array
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* request.transformScopes((scopes) => {
|
|
26
|
+
* return scopes.map(scope => `https://provider.com/auth/${scope}`)
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
12
29
|
*/
|
|
13
30
|
transformScopes(callback: (scopes: LiteralStringUnion<Scopes>[]) => string[]): this;
|
|
14
31
|
/**
|
|
15
|
-
* Define
|
|
32
|
+
* Define the scopes to request during authorization. This replaces
|
|
33
|
+
* any previously set scopes.
|
|
34
|
+
*
|
|
35
|
+
* @param scopes - Array of scope strings to request
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* request.scopes(['user:email', 'read:org'])
|
|
40
|
+
* ```
|
|
16
41
|
*/
|
|
17
42
|
scopes(scopes: LiteralStringUnion<Scopes>[]): this;
|
|
18
43
|
/**
|
|
19
|
-
* Merge
|
|
44
|
+
* Merge additional scopes with any existing scopes. This is useful
|
|
45
|
+
* for adding scopes without replacing the default ones.
|
|
46
|
+
*
|
|
47
|
+
* @param scopes - Array of scope strings to merge
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* request
|
|
52
|
+
* .scopes(['user:email'])
|
|
53
|
+
* .mergeScopes(['read:org'])
|
|
54
|
+
* ```
|
|
20
55
|
*/
|
|
21
56
|
mergeScopes(scopes: LiteralStringUnion<Scopes>[]): this;
|
|
22
57
|
/**
|
|
23
|
-
* Clear existing scopes
|
|
58
|
+
* Clear all existing scopes from the authorization request.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* request.clearScopes().scopes(['user'])
|
|
63
|
+
* ```
|
|
24
64
|
*/
|
|
25
65
|
clearScopes(): this;
|
|
26
66
|
}
|
package/build/src/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
2
|
import type { ConfigProvider } from '@adonisjs/core/types';
|
|
3
3
|
import type { Oauth2AccessToken, Oauth1RequestToken, Oauth1AccessToken, Oauth1ClientConfig, Oauth2ClientConfig, ApiRequestContract, RedirectRequestContract as ClientRequestContract } from '@poppinss/oauth-client/types';
|
|
4
|
-
import type { AllyManager } from './ally_manager.
|
|
4
|
+
import type { AllyManager } from './ally_manager.ts';
|
|
5
5
|
export type { Oauth2AccessToken };
|
|
6
6
|
export type { Oauth1AccessToken };
|
|
7
7
|
export type { Oauth1RequestToken };
|
package/build/src/types.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/ally",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-next.0",
|
|
4
4
|
"description": "Social authentication provider for AdonisJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -22,68 +22,52 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"pretest": "npm run lint",
|
|
24
24
|
"test": "c8 npm run quick:test",
|
|
25
|
-
"
|
|
25
|
+
"lint": "eslint",
|
|
26
|
+
"format": "prettier --write .",
|
|
26
27
|
"typecheck": "tsc --noEmit",
|
|
27
28
|
"start": "node --import=ts-node-maintained/register/esm examples/app.ts",
|
|
28
|
-
"
|
|
29
|
+
"clean": "del-cli build",
|
|
29
30
|
"precompile": "npm run lint && npm run clean",
|
|
31
|
+
"copy:templates": "copyfiles --up=1 \"stubs/**/*.stub\" build",
|
|
30
32
|
"compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
|
|
31
33
|
"postcompile": "npm run copy:templates",
|
|
32
|
-
"build": "npm run compile",
|
|
33
34
|
"prepublishOnly": "npm run build",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"release": "release-it",
|
|
35
|
+
"build": "npm run compile",
|
|
36
|
+
"release": "npx release-it",
|
|
37
37
|
"version": "npm run build",
|
|
38
|
-
"
|
|
39
|
-
"quick:test": "node --enable-source-maps --import
|
|
38
|
+
"index:commands": "adonis-kit index build/commands",
|
|
39
|
+
"quick:test": "cross-env NODE_DEBUG=\"adonisjs:ally\" node --enable-source-maps --import=@poppinss/ts-exec bin/test.ts"
|
|
40
40
|
},
|
|
41
|
-
"keywords": [
|
|
42
|
-
"adonis",
|
|
43
|
-
"adonisjs",
|
|
44
|
-
"social-auth",
|
|
45
|
-
"oauth"
|
|
46
|
-
],
|
|
47
|
-
"author": "Harminder Virk <virk@adonisjs.com>",
|
|
48
|
-
"contributors": [
|
|
49
|
-
"Romain Lanz <romain.lanz@pm.me>"
|
|
50
|
-
],
|
|
51
|
-
"license": "MIT",
|
|
52
41
|
"devDependencies": {
|
|
53
|
-
"@adonisjs/assembler": "^
|
|
54
|
-
"@adonisjs/core": "^
|
|
55
|
-
"@adonisjs/eslint-config": "^
|
|
56
|
-
"@adonisjs/prettier-config": "^1.4.
|
|
57
|
-
"@adonisjs/tsconfig": "^
|
|
58
|
-
"@
|
|
59
|
-
"@commitlint/config-conventional": "^19.7.1",
|
|
60
|
-
"@japa/assert": "^4.0.1",
|
|
42
|
+
"@adonisjs/assembler": "^8.0.0-next.14",
|
|
43
|
+
"@adonisjs/core": "^7.0.0-next.8",
|
|
44
|
+
"@adonisjs/eslint-config": "^3.0.0-next.4",
|
|
45
|
+
"@adonisjs/prettier-config": "^1.4.5",
|
|
46
|
+
"@adonisjs/tsconfig": "^2.0.0-next.3",
|
|
47
|
+
"@japa/assert": "^4.1.1",
|
|
61
48
|
"@japa/expect-type": "^2.0.3",
|
|
62
49
|
"@japa/file-system": "^2.3.2",
|
|
63
|
-
"@japa/runner": "^4.
|
|
64
|
-
"@
|
|
65
|
-
"@
|
|
66
|
-
"@types/node": "^
|
|
50
|
+
"@japa/runner": "^4.4.0",
|
|
51
|
+
"@poppinss/ts-exec": "^1.4.1",
|
|
52
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
53
|
+
"@types/node": "^24.10.0",
|
|
67
54
|
"c8": "^10.1.3",
|
|
68
55
|
"copyfiles": "^2.4.1",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"eslint": "^9.
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"ts-node-maintained": "^10.9.5",
|
|
77
|
-
"tsup": "^8.4.0",
|
|
78
|
-
"typescript": "^5.8.2"
|
|
56
|
+
"cross-env": "^10.1.0",
|
|
57
|
+
"del-cli": "^7.0.0",
|
|
58
|
+
"eslint": "^9.39.0",
|
|
59
|
+
"prettier": "^3.6.2",
|
|
60
|
+
"release-it": "^19.0.5",
|
|
61
|
+
"tsup": "^8.5.0",
|
|
62
|
+
"typescript": "^5.9.3"
|
|
79
63
|
},
|
|
80
64
|
"dependencies": {
|
|
81
|
-
"@poppinss/oauth-client": "^7.0.
|
|
82
|
-
"@poppinss/utils": "^6.9.2"
|
|
65
|
+
"@poppinss/oauth-client": "^7.0.1"
|
|
83
66
|
},
|
|
84
67
|
"peerDependencies": {
|
|
85
|
-
"@adonisjs/core": "^
|
|
68
|
+
"@adonisjs/core": "^7.0.0-next.8"
|
|
86
69
|
},
|
|
70
|
+
"homepage": "https://github.com/adonisjs/ally#readme",
|
|
87
71
|
"repository": {
|
|
88
72
|
"type": "git",
|
|
89
73
|
"url": "git+https://github.com/adonisjs/ally.git"
|
|
@@ -91,10 +75,34 @@
|
|
|
91
75
|
"bugs": {
|
|
92
76
|
"url": "https://github.com/adonisjs/ally/issues"
|
|
93
77
|
},
|
|
94
|
-
"
|
|
78
|
+
"keywords": [
|
|
79
|
+
"adonis",
|
|
80
|
+
"adonisjs",
|
|
81
|
+
"social-auth",
|
|
82
|
+
"oauth"
|
|
83
|
+
],
|
|
84
|
+
"author": "Harminder Virk <virk@adonisjs.com>",
|
|
85
|
+
"contributors": [
|
|
86
|
+
"Romain Lanz <romain.lanz@pm.me>"
|
|
87
|
+
],
|
|
88
|
+
"license": "MIT",
|
|
95
89
|
"publishConfig": {
|
|
96
|
-
"
|
|
97
|
-
"
|
|
90
|
+
"access": "public",
|
|
91
|
+
"provenance": true
|
|
92
|
+
},
|
|
93
|
+
"tsup": {
|
|
94
|
+
"entry": [
|
|
95
|
+
"./index.ts",
|
|
96
|
+
"./src/types.ts",
|
|
97
|
+
"./src/drivers/*.ts",
|
|
98
|
+
"./providers/ally_provider.ts"
|
|
99
|
+
],
|
|
100
|
+
"outDir": "./build",
|
|
101
|
+
"clean": true,
|
|
102
|
+
"format": "esm",
|
|
103
|
+
"dts": false,
|
|
104
|
+
"sourcemap": false,
|
|
105
|
+
"target": "esnext"
|
|
98
106
|
},
|
|
99
107
|
"release-it": {
|
|
100
108
|
"git": {
|
|
@@ -120,12 +128,6 @@
|
|
|
120
128
|
}
|
|
121
129
|
}
|
|
122
130
|
},
|
|
123
|
-
"prettier": "@adonisjs/prettier-config",
|
|
124
|
-
"commitlint": {
|
|
125
|
-
"extends": [
|
|
126
|
-
"@commitlint/config-conventional"
|
|
127
|
-
]
|
|
128
|
-
},
|
|
129
131
|
"c8": {
|
|
130
132
|
"reporter": [
|
|
131
133
|
"text",
|
|
@@ -138,18 +140,5 @@
|
|
|
138
140
|
"stubs/**"
|
|
139
141
|
]
|
|
140
142
|
},
|
|
141
|
-
"
|
|
142
|
-
"entry": [
|
|
143
|
-
"./index.ts",
|
|
144
|
-
"./src/types.ts",
|
|
145
|
-
"./src/drivers/*.ts",
|
|
146
|
-
"./providers/ally_provider.ts"
|
|
147
|
-
],
|
|
148
|
-
"outDir": "./build",
|
|
149
|
-
"clean": true,
|
|
150
|
-
"format": "esm",
|
|
151
|
-
"dts": false,
|
|
152
|
-
"sourcemap": true,
|
|
153
|
-
"target": "esnext"
|
|
154
|
-
}
|
|
143
|
+
"prettier": "@adonisjs/prettier-config"
|
|
155
144
|
}
|
package/build/chunk-GWAQFMNS.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
E_OAUTH_MISSING_CODE,
|
|
3
|
-
E_OAUTH_STATE_MISMATCH,
|
|
4
|
-
RedirectRequest
|
|
5
|
-
} from "./chunk-N72DEJC2.js";
|
|
6
|
-
|
|
7
|
-
// src/abstract_drivers/oauth2.ts
|
|
8
|
-
import { Exception } from "@poppinss/utils";
|
|
9
|
-
import { Oauth2Client } from "@poppinss/oauth-client/oauth2";
|
|
10
|
-
var Oauth2Driver = class extends Oauth2Client {
|
|
11
|
-
constructor(ctx, config) {
|
|
12
|
-
super(config);
|
|
13
|
-
this.ctx = ctx;
|
|
14
|
-
this.config = config;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Is the authorization process stateless?
|
|
18
|
-
*/
|
|
19
|
-
isStateless = false;
|
|
20
|
-
/**
|
|
21
|
-
* Oauth client version
|
|
22
|
-
*/
|
|
23
|
-
version = "oauth2";
|
|
24
|
-
/**
|
|
25
|
-
* The value of state read from the cookies.
|
|
26
|
-
*/
|
|
27
|
-
stateCookieValue;
|
|
28
|
-
/**
|
|
29
|
-
* The Oauth2Client will use the instance returned from this method to
|
|
30
|
-
* build the redirect url
|
|
31
|
-
*/
|
|
32
|
-
urlBuilder(url) {
|
|
33
|
-
return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Loads the value of state from the cookie and removes it right
|
|
37
|
-
* away. We read the cookie value and clear it during the
|
|
38
|
-
* current request lifecycle.
|
|
39
|
-
*
|
|
40
|
-
* :::::
|
|
41
|
-
* NOTE
|
|
42
|
-
* :::::
|
|
43
|
-
*
|
|
44
|
-
* This child class must call this method inside the constructor.
|
|
45
|
-
*/
|
|
46
|
-
loadState() {
|
|
47
|
-
if (this.isStateless) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.stateCookieValue = this.ctx.request.encryptedCookie(this.stateCookieName);
|
|
51
|
-
this.ctx.response.clearCookie(this.stateCookieName);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Persists the state inside the cookie
|
|
55
|
-
*/
|
|
56
|
-
#persistState() {
|
|
57
|
-
if (this.isStateless) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const state = this.getState();
|
|
61
|
-
this.ctx.response.encryptedCookie(this.stateCookieName, state, {
|
|
62
|
-
sameSite: false,
|
|
63
|
-
httpOnly: true
|
|
64
|
-
});
|
|
65
|
-
return state;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Perform stateless authentication. Only applicable for Oauth2 client
|
|
69
|
-
*/
|
|
70
|
-
stateless() {
|
|
71
|
-
this.isStateless = true;
|
|
72
|
-
return this;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Returns the redirect URL for the request.
|
|
76
|
-
*/
|
|
77
|
-
async redirectUrl(callback) {
|
|
78
|
-
const url = this.getRedirectUrl(callback);
|
|
79
|
-
return url;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Redirect user for authorization.
|
|
83
|
-
*/
|
|
84
|
-
async redirect(callback) {
|
|
85
|
-
const url = await this.redirectUrl((request) => {
|
|
86
|
-
const state = this.#persistState();
|
|
87
|
-
state && request.param(this.stateParamName, state);
|
|
88
|
-
if (typeof callback === "function") {
|
|
89
|
-
callback(request);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
this.ctx.response.redirect(url);
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Find if there is a state mismatch
|
|
96
|
-
*/
|
|
97
|
-
stateMisMatch() {
|
|
98
|
-
if (this.isStateless) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
return this.stateCookieValue !== this.ctx.request.input(this.stateParamName);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Find if there is an error post redirect
|
|
105
|
-
*/
|
|
106
|
-
hasError() {
|
|
107
|
-
return !!this.getError();
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Get the post redirect error
|
|
111
|
-
*/
|
|
112
|
-
getError() {
|
|
113
|
-
const error = this.ctx.request.input(this.errorParamName);
|
|
114
|
-
if (error) {
|
|
115
|
-
return error;
|
|
116
|
-
}
|
|
117
|
-
if (!this.hasCode()) {
|
|
118
|
-
return "unknown_error";
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Returns the authorization code
|
|
124
|
-
*/
|
|
125
|
-
getCode() {
|
|
126
|
-
return this.ctx.request.input(this.codeParamName, null);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Find it the code exists
|
|
130
|
-
*/
|
|
131
|
-
hasCode() {
|
|
132
|
-
return !!this.getCode();
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Get access token
|
|
136
|
-
*/
|
|
137
|
-
async accessToken(callback) {
|
|
138
|
-
if (this.hasError()) {
|
|
139
|
-
throw new E_OAUTH_MISSING_CODE([this.codeParamName]);
|
|
140
|
-
}
|
|
141
|
-
if (this.stateMisMatch()) {
|
|
142
|
-
throw new E_OAUTH_STATE_MISMATCH();
|
|
143
|
-
}
|
|
144
|
-
return this.getAccessToken((request) => {
|
|
145
|
-
request.field(this.codeParamName, this.getCode());
|
|
146
|
-
if (typeof callback === "function") {
|
|
147
|
-
callback(request);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Not applicable with Oauth2
|
|
153
|
-
*/
|
|
154
|
-
async userFromTokenAndSecret() {
|
|
155
|
-
throw new Exception(
|
|
156
|
-
'"userFromTokenAndSecret" is not applicable with Oauth2. Use "userFromToken" instead'
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
export {
|
|
162
|
-
Oauth2Driver
|
|
163
|
-
};
|
|
164
|
-
//# sourceMappingURL=chunk-GWAQFMNS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/abstract_drivers/oauth2.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { Exception } from '@poppinss/utils'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport { Oauth2Client } from '@poppinss/oauth-client/oauth2'\n\nimport {\n AllyUserContract,\n Oauth2AccessToken,\n Oauth2DriverConfig,\n ApiRequestContract,\n AllyDriverContract,\n RedirectRequestContract,\n} from '../types.js'\n\nimport * as errors from '../errors.js'\nimport { RedirectRequest } from '../redirect_request.js'\n\n/**\n * Abstract implementation for an Oauth2 driver\n */\nexport abstract class Oauth2Driver<Token extends Oauth2AccessToken, Scopes extends string>\n extends Oauth2Client<Token>\n implements AllyDriverContract<Token, Scopes>\n{\n /**\n * Is the authorization process stateless?\n */\n protected isStateless: boolean = false\n\n /**\n * The cookie name for storing the CSRF token. Must be unique for your\n * driver. One option is to prefix the driver name. For example:\n * `gh_oauth_state`\n */\n protected abstract stateCookieName: string\n\n /**\n * The parameter in which to send the state to the oauth provider. The same\n * input is used to retrieve the state post redirect as well.\n *\n * You must check the auth provider docs to find it\n */\n protected abstract stateParamName: string\n\n /**\n * The parameter name from which to fetch the error message or error code\n * post redirect.\n *\n * You must check the auth provider docs to find it\n */\n protected abstract errorParamName: string\n\n /**\n * The parameter name from which to fetch the authorization code. It is usually\n * named as \"code\".\n *\n * You must check the auth provider docs to find it\n */\n protected abstract codeParamName: string\n\n /**\n * Authorization URL for the auth provider. The user will be redirected\n * to this URL\n */\n protected abstract authorizeUrl: string\n\n /**\n * The URL to hit to get an access token\n */\n protected abstract accessTokenUrl: string\n\n /**\n * The query param name for defining the Authorization scopes.\n * Mostly it is `scope`\n */\n protected abstract scopeParamName: string\n\n /**\n * The identifier for joining multiple scopes. Mostly it is a space.\n */\n protected abstract scopesSeparator: string\n\n /**\n * Returns details for the authorized user\n */\n abstract user(callback?: (request: ApiRequestContract) => void): Promise<AllyUserContract<Token>>\n\n /**\n * Finds the user by access token\n */\n abstract userFromToken(\n token: string,\n callback?: (request: ApiRequestContract) => void\n ): Promise<AllyUserContract<{ token: string; type: 'bearer' }>>\n\n /**\n * Find if the current error code is for access denied\n */\n abstract accessDenied(): boolean\n\n /**\n * Oauth client version\n */\n version = 'oauth2' as const\n\n /**\n * The value of state read from the cookies.\n */\n protected stateCookieValue?: string\n\n constructor(\n protected ctx: HttpContext,\n public config: Oauth2DriverConfig\n ) {\n super(config)\n }\n\n /**\n * The Oauth2Client will use the instance returned from this method to\n * build the redirect url\n */\n protected urlBuilder(url: string) {\n return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator)\n }\n\n /**\n * Loads the value of state from the cookie and removes it right\n * away. We read the cookie value and clear it during the\n * current request lifecycle.\n *\n * :::::\n * NOTE\n * :::::\n *\n * This child class must call this method inside the constructor.\n */\n protected loadState() {\n if (this.isStateless) {\n return\n }\n\n this.stateCookieValue = this.ctx.request.encryptedCookie(this.stateCookieName)\n this.ctx.response.clearCookie(this.stateCookieName)\n }\n\n /**\n * Persists the state inside the cookie\n */\n #persistState(): string | undefined {\n if (this.isStateless) {\n return\n }\n\n const state = this.getState()\n this.ctx.response.encryptedCookie(this.stateCookieName, state, {\n sameSite: false,\n httpOnly: true,\n })\n\n return state\n }\n\n /**\n * Perform stateless authentication. Only applicable for Oauth2 client\n */\n stateless(): this {\n this.isStateless = true\n return this\n }\n\n /**\n * Returns the redirect URL for the request.\n */\n async redirectUrl(\n callback?: (request: RedirectRequestContract<Scopes>) => void\n ): Promise<string> {\n const url = this.getRedirectUrl(callback as any)\n return url\n }\n\n /**\n * Redirect user for authorization.\n */\n async redirect(callback?: (request: RedirectRequestContract<Scopes>) => void): Promise<void> {\n const url = await this.redirectUrl((request) => {\n const state = this.#persistState()\n state && request.param(this.stateParamName, state)\n\n if (typeof callback === 'function') {\n callback(request)\n }\n })\n\n this.ctx.response.redirect(url)\n }\n\n /**\n * Find if there is a state mismatch\n */\n stateMisMatch(): boolean {\n if (this.isStateless) {\n return false\n }\n\n return this.stateCookieValue !== this.ctx.request.input(this.stateParamName)\n }\n\n /**\n * Find if there is an error post redirect\n */\n hasError(): boolean {\n return !!this.getError()\n }\n\n /**\n * Get the post redirect error\n */\n getError(): string | null {\n const error = this.ctx.request.input(this.errorParamName)\n if (error) {\n return error\n }\n\n if (!this.hasCode()) {\n return 'unknown_error'\n }\n\n return null\n }\n\n /**\n * Returns the authorization code\n */\n getCode(): string | null {\n return this.ctx.request.input(this.codeParamName, null)\n }\n\n /**\n * Find it the code exists\n */\n hasCode(): boolean {\n return !!this.getCode()\n }\n\n /**\n * Get access token\n */\n async accessToken(callback?: (request: ApiRequestContract) => void): Promise<Token> {\n /**\n * We expect the user to handle errors before calling this method\n */\n if (this.hasError()) {\n throw new errors.E_OAUTH_MISSING_CODE([this.codeParamName])\n }\n\n /**\n * We expect the user to properly handle the state mis-match use case before\n * calling this method\n */\n if (this.stateMisMatch()) {\n throw new errors.E_OAUTH_STATE_MISMATCH()\n }\n\n /**\n * Get access token by providing the authorization code\n */\n return this.getAccessToken((request) => {\n request.field(this.codeParamName, this.getCode())\n\n if (typeof callback === 'function') {\n callback(request)\n }\n })\n }\n\n /**\n * Not applicable with Oauth2\n */\n async userFromTokenAndSecret(): Promise<never> {\n throw new Exception(\n '\"userFromTokenAndSecret\" is not applicable with Oauth2. Use \"userFromToken\" instead'\n )\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/redirect_request.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { createError } from '@poppinss/utils'\n\nexport const E_OAUTH_MISSING_CODE = createError<[string]>(\n 'Cannot request access token. Redirect request is missing the \"%s\" param',\n 'E_OAUTH_MISSING_CODE',\n 500\n)\n\nexport const E_OAUTH_STATE_MISMATCH = createError(\n 'Unable to verify re-redirect state',\n 'E_OAUTH_STATE_MISMATCH',\n 400\n)\n","/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { UrlBuilder } from '@poppinss/oauth-client'\nimport { LiteralStringUnion } from './types.js'\n\n/**\n * Redirect request with first class support for defining scopes.\n */\nexport class RedirectRequest<Scopes extends string> extends UrlBuilder {\n #scopesTransformer: undefined | ((scopes: LiteralStringUnion<Scopes>[]) => string[])\n #scopeParamName: string\n #scopeSeparator: string\n\n constructor(baseUrl: string, scopeParamName: string, scopeSeparator: string) {\n super(baseUrl)\n this.#scopeParamName = scopeParamName\n this.#scopeSeparator = scopeSeparator\n }\n\n /**\n * Register a custom function to transform scopes. Exposed for drivers\n * to implement.\n */\n transformScopes(callback: (scopes: LiteralStringUnion<Scopes>[]) => string[]): this {\n this.#scopesTransformer = callback\n return this\n }\n\n /**\n * Define an array of scopes.\n */\n scopes(scopes: LiteralStringUnion<Scopes>[]): this {\n if (typeof this.#scopesTransformer === 'function') {\n scopes = this.#scopesTransformer(scopes)\n }\n\n this.param(this.#scopeParamName, scopes.join(this.#scopeSeparator))\n return this\n }\n\n /**\n * Merge to existing scopes\n */\n mergeScopes(scopes: LiteralStringUnion<Scopes>[]): this {\n if (typeof this.#scopesTransformer === 'function') {\n scopes = this.#scopesTransformer(scopes)\n }\n\n const existingScopes = this.getParams()[this.#scopeParamName]\n const scopesString = scopes.join(this.#scopeSeparator)\n\n if (!existingScopes) {\n this.param(this.#scopeParamName, scopesString)\n return this\n }\n\n this.param(this.#scopeParamName, `${existingScopes}${this.#scopeSeparator}${scopesString}`)\n return this\n }\n\n /**\n * Clear existing scopes\n */\n clearScopes(): this {\n this.clearParam(this.#scopeParamName)\n return this\n }\n}\n"],"mappings":";;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,SAAS,mBAAmB;AAErB,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF;;;ACZA,SAAS,kBAAkB;AAMpB,IAAM,kBAAN,cAAqD,WAAW;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,gBAAwB,gBAAwB;AAC3E,UAAM,OAAO;AACb,SAAK,kBAAkB;AACvB,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,UAAoE;AAClF,SAAK,qBAAqB;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAA4C;AACjD,QAAI,OAAO,KAAK,uBAAuB,YAAY;AACjD,eAAS,KAAK,mBAAmB,MAAM;AAAA,IACzC;AAEA,SAAK,MAAM,KAAK,iBAAiB,OAAO,KAAK,KAAK,eAAe,CAAC;AAClE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAA4C;AACtD,QAAI,OAAO,KAAK,uBAAuB,YAAY;AACjD,eAAS,KAAK,mBAAmB,MAAM;AAAA,IACzC;AAEA,UAAM,iBAAiB,KAAK,UAAU,EAAE,KAAK,eAAe;AAC5D,UAAM,eAAe,OAAO,KAAK,KAAK,eAAe;AAErD,QAAI,CAAC,gBAAgB;AACnB,WAAK,MAAM,KAAK,iBAAiB,YAAY;AAC7C,aAAO;AAAA,IACT;AAEA,SAAK,MAAM,KAAK,iBAAiB,GAAG,cAAc,GAAG,KAAK,eAAe,GAAG,YAAY,EAAE;AAC1F,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,cAAoB;AAClB,SAAK,WAAW,KAAK,eAAe;AACpC,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ally_manager.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { RuntimeException } from '@poppinss/utils'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { AllyDriverContract, AllyManagerDriverFactory } from './types.js'\n\n/**\n * AllyManager is used to create instances of a social drivers during an\n * HTTP request. The drivers are cached during the lifecycle of a request.\n */\nexport class AllyManager<KnownSocialProviders extends Record<string, AllyManagerDriverFactory>> {\n #ctx: HttpContext\n #driversCache: Map<keyof KnownSocialProviders, AllyDriverContract<any, any>> = new Map()\n\n constructor(\n public config: KnownSocialProviders,\n ctx: HttpContext\n ) {\n this.#ctx = ctx\n }\n\n /**\n * Returns the driver instance of a social provider\n */\n use<SocialProvider extends keyof KnownSocialProviders>(\n provider: SocialProvider\n ): ReturnType<KnownSocialProviders[SocialProvider]> {\n if (this.#driversCache.has(provider)) {\n return this.#driversCache.get(provider) as ReturnType<KnownSocialProviders[SocialProvider]>\n }\n\n const driver = this.config[provider]\n if (!driver) {\n throw new RuntimeException(\n `Unknown ally provider \"${String(\n provider\n )}\". Make sure it is registered inside the config/ally.ts file`\n )\n }\n\n const driverInstance = driver(this.#ctx) as ReturnType<KnownSocialProviders[SocialProvider]>\n this.#driversCache.set(provider, driverInstance)\n\n return driverInstance\n }\n}\n"],"mappings":";AASA,SAAS,wBAAwB;AAQ1B,IAAM,cAAN,MAAyF;AAAA,EAI9F,YACS,QACP,KACA;AAFO;AAGP,SAAK,OAAO;AAAA,EACd;AAAA,EARA;AAAA,EACA,gBAA+E,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAYvF,IACE,UACkD;AAClD,QAAI,KAAK,cAAc,IAAI,QAAQ,GAAG;AACpC,aAAO,KAAK,cAAc,IAAI,QAAQ;AAAA,IACxC;AAEA,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,0BAA0B;AAAA,UACxB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,iBAAiB,OAAO,KAAK,IAAI;AACvC,SAAK,cAAc,IAAI,UAAU,cAAc;AAE/C,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/abstract_drivers/oauth1.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { Exception } from '@poppinss/utils'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport { Oauth1Client } from '@poppinss/oauth-client/oauth1'\n\nimport {\n AllyUserContract,\n Oauth1AccessToken,\n Oauth1DriverConfig,\n ApiRequestContract,\n AllyDriverContract,\n RedirectRequestContract,\n} from '../types.js'\n\nimport * as errors from '../errors.js'\nimport { RedirectRequest } from '../redirect_request.js'\n\n/**\n * Abstract implementation for an Oauth1 driver\n */\nexport abstract class Oauth1Driver<Token extends Oauth1AccessToken, Scopes extends string>\n extends Oauth1Client<Token>\n implements AllyDriverContract<Token, Scopes>\n{\n /**\n * The cookie name for storing the \"oauth_token\". Must be unique for your\n * driver. One option is to prefix the driver name. For example:\n * `twitter_oauth_token`\n */\n protected abstract oauthTokenCookieName: string\n\n /**\n * Name of the \"oauth_token\" param. This is the query string value post\n * authorization redirect\n */\n protected abstract oauthTokenParamName: string\n\n /**\n * Name of the \"oauth_verifier\" param. This is the query string value post\n * authorization redirect\n */\n protected abstract oauthTokenVerifierName: string\n\n /**\n * The parameter name from which to fetch the error message or error code\n * post redirect.\n *\n * You must check the auth provider docs to find it\n */\n protected abstract errorParamName: string\n\n /**\n * Request token URL for the auth provider. The initial set of tokens\n * are generated from this url\n */\n protected abstract requestTokenUrl: string\n\n /**\n * Authorization URL for the auth provider. The user will be redirected\n * to this URL\n */\n protected abstract authorizeUrl: string\n\n /**\n * The URL to hit to get an access token\n */\n protected abstract accessTokenUrl: string\n\n /**\n * The query param name for defining the Authorization scopes.\n * Mostly it is `scope`. Leave to empty string when scopes\n * are not applicable\n */\n protected abstract scopeParamName: string\n\n /**\n * The identifier for joining multiple scopes. Mostly it is a space.\n */\n protected abstract scopesSeparator: string\n\n /**\n * Returns details for the authorized user\n */\n abstract user(callback?: (request: ApiRequestContract) => void): Promise<AllyUserContract<Token>>\n\n /**\n * Finds the user by access token\n */\n abstract userFromTokenAndSecret(\n token: string,\n secret: string,\n callback?: (request: ApiRequestContract) => void\n ): Promise<AllyUserContract<{ token: string; secret: string }>>\n\n /**\n * Find if the current error code is for access denied\n */\n abstract accessDenied(): boolean\n\n /**\n * Oauth client version\n */\n version = 'oauth1' as const\n\n /**\n * The value of \"oauth_token\" and \"oauth_secret\" from the cookies\n */\n protected oauthTokenCookieValue?: string\n protected oauthSecretCookieValue?: string\n\n /**\n * The cookie name for storing the secret\n */\n protected get oauthSecretCookieName() {\n return `${this.oauthTokenCookieName}_secret`\n }\n\n constructor(\n protected ctx: HttpContext,\n public config: Oauth1DriverConfig\n ) {\n super(config)\n }\n\n /**\n * The Oauth1Client will use the instance returned from this method to\n * build the redirect url\n */\n protected urlBuilder(url: string) {\n return new RedirectRequest(url, this.scopeParamName, this.scopesSeparator)\n }\n\n /**\n * Loads the value of state from the cookie and removes it right\n * away. We read the cookie value and clear it during the\n * current request lifecycle.\n *\n * :::::\n * NOTE\n * :::::\n *\n * This child class must call this method inside the constructor.\n */\n protected loadState() {\n /**\n * Read and cache in-memory\n */\n this.oauthTokenCookieValue = this.ctx.request.encryptedCookie(this.oauthTokenCookieName)\n this.oauthSecretCookieValue = this.ctx.request.encryptedCookie(this.oauthSecretCookieName)\n\n /**\n * Clear cookies\n */\n this.ctx.response.clearCookie(this.oauthTokenCookieName)\n this.ctx.response.clearCookie(this.oauthSecretCookieName)\n }\n\n /**\n * Persists the token (aka state) inside the cookie\n */\n #persistToken(token: string): void {\n this.ctx.response.encryptedCookie(this.oauthTokenCookieName, token, {\n sameSite: false,\n httpOnly: true,\n })\n }\n\n /**\n * Persists the secret inside the cookie\n */\n #persistSecret(secret: string): void {\n this.ctx.response.encryptedCookie(this.oauthSecretCookieName, secret, {\n sameSite: false,\n httpOnly: true,\n })\n }\n\n /**\n * Perform stateless authentication. Only applicable for Oauth1 client\n */\n stateless(): never {\n throw new Exception('OAuth1 does not support stateless authorization')\n }\n\n /**\n * Returns the redirect URL for the request.\n */\n async redirectUrl(\n callback?: (request: RedirectRequestContract<Scopes>) => void\n ): Promise<string> {\n return this.getRedirectUrl(callback as any)\n }\n\n /**\n * Redirect user for authorization.\n */\n async redirect(callback?: (request: RedirectRequestContract<Scopes>) => void): Promise<void> {\n const { token, secret } = await this.getRequestToken()\n\n /**\n * Storing token and secret inside cookies. We need them\n * later\n */\n this.#persistToken(token)\n this.#persistSecret(secret)\n\n const url = await this.redirectUrl((request) => {\n request.param(this.oauthTokenParamName, token)\n\n if (typeof callback === 'function') {\n callback(request)\n }\n })\n\n this.ctx.response.redirect(url)\n }\n\n /**\n * Find if there is a state mismatch\n */\n stateMisMatch(): boolean {\n return this.oauthTokenCookieValue !== this.ctx.request.input(this.oauthTokenParamName)\n }\n\n /**\n * Find if there is an error post redirect\n */\n hasError(): boolean {\n return !!this.getError()\n }\n\n /**\n * Get the post redirect error\n */\n getError(): string | null {\n const error = this.ctx.request.input(this.errorParamName)\n if (error) {\n return error\n }\n\n if (!this.hasCode()) {\n return 'unknown_error'\n }\n\n return null\n }\n\n /**\n * Returns the \"oauth_verifier\" token\n */\n getCode(): string | null {\n return this.ctx.request.input(this.oauthTokenVerifierName, null)\n }\n\n /**\n * Find it the code exists\n */\n hasCode(): boolean {\n return !!this.getCode()\n }\n\n /**\n * Get access token\n */\n async accessToken(callback?: (request: ApiRequestContract) => void): Promise<Token> {\n /**\n * We expect the user to handle errors before calling this method\n */\n if (this.hasError()) {\n throw new errors.E_OAUTH_MISSING_CODE([this.oauthTokenVerifierName])\n }\n\n /**\n * We expect the user to properly handle the state mis-match use case before\n * calling this method\n */\n if (this.stateMisMatch()) {\n throw new errors.E_OAUTH_STATE_MISMATCH()\n }\n\n /**\n * Get access token by providing the authorization code\n */\n return this.getAccessToken(\n { token: this.oauthTokenCookieValue!, secret: this.oauthSecretCookieValue! },\n (request) => {\n request.oauth1Param(this.oauthTokenVerifierName, this.getCode())\n\n if (typeof callback === 'function') {\n callback(request)\n }\n }\n )\n }\n\n /**\n * Not applicable with Oauth1\n */\n async userFromToken(): Promise<never> {\n throw new Exception(\n '\"userFromToken\" is not available with Oauth1. Use \"userFromTokenAndSecret\" instead'\n )\n }\n}\n"],"mappings":"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","names":[]}
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../stubs/main.ts","../configure.ts","../src/define_config.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nexport { HttpClient as ApiRequest } from '@poppinss/oauth-client'\n\nexport * as errors from './src/errors.js'\nexport { configure } from './configure.js'\nexport { stubsRoot } from './stubs/main.js'\nexport { AllyManager } from './src/ally_manager.js'\nexport { defineConfig, services } from './src/define_config.js'\n\nexport { RedirectRequest } from './src/redirect_request.js'\nexport { Oauth1Driver } from './src/abstract_drivers/oauth1.js'\nexport { Oauth2Driver } from './src/abstract_drivers/oauth2.js'\n","/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { getDirname } from '@poppinss/utils'\n\nexport const stubsRoot = getDirname(import.meta.url)\n","/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type Configure from '@adonisjs/core/commands/configure'\nimport { stubsRoot } from './stubs/main.js'\n\n/**\n * List of available providers\n */\nconst AVAILABLE_PROVIDERS = [\n 'discord',\n 'facebook',\n 'github',\n 'google',\n 'linkedin',\n 'linkedinOpenidConnect',\n 'spotify',\n 'twitter',\n]\n\n/**\n * Configures the package\n */\nexport async function configure(command: Configure) {\n /**\n * Read providers from the CLI flags\n */\n let selectedProviders: string[] | string | undefined = command.parsedFlags.providers\n\n /**\n * Otherwise force prompt for selection\n */\n if (!selectedProviders) {\n selectedProviders = await command.prompt.multiple(\n 'Select the social auth providers you plan to use',\n AVAILABLE_PROVIDERS,\n {\n validate(value) {\n return !value || !value.length\n ? 'Select a social provider to configure the package'\n : true\n },\n }\n )\n }\n\n /**\n * Cast CLI string value to an array\n */\n let providers = (\n typeof selectedProviders === 'string' ? [selectedProviders] : selectedProviders\n ) as string[]\n\n /**\n * Validate CLI selection to contain known providers\n */\n const unknownProvider = providers.find((provider) => !AVAILABLE_PROVIDERS.includes(provider))\n if (unknownProvider) {\n command.exitCode = 1\n command.logger.error(`Invalid social provider \"${unknownProvider}\"`)\n return\n }\n\n const codemods = await command.createCodemods()\n\n /**\n * Publish config file\n */\n await codemods.makeUsingStub(stubsRoot, 'config/ally.stub', {\n providers: providers.map((provider) => {\n return { provider, envPrefix: provider.toUpperCase() }\n }),\n })\n\n /**\n * Publish provider\n */\n await codemods.updateRcFile((rcFile) => {\n rcFile.addProvider('@adonisjs/ally/ally_provider')\n })\n\n /**\n * Define env variables for the selected providers\n */\n await codemods.defineEnvVariables(\n providers.reduce<Record<string, string>>((result, provider) => {\n result[`${provider.toUpperCase()}_CLIENT_ID`] = ''\n result[`${provider.toUpperCase()}_CLIENT_SECRET`] = ''\n return result\n }, {})\n )\n\n /**\n * Define env variables validation for the selected providers\n */\n await codemods.defineEnvValidations({\n variables: providers.reduce<Record<string, string>>((result, provider) => {\n result[`${provider.toUpperCase()}_CLIENT_ID`] = 'Env.schema.string()'\n result[`${provider.toUpperCase()}_CLIENT_SECRET`] = 'Env.schema.string()'\n return result\n }, {}),\n leadingComment: 'Variables for configuring ally package',\n })\n}\n","/*\n * @adonisjs/ally\n *\n * (c) Ally\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { configProvider } from '@adonisjs/core'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { ConfigProvider } from '@adonisjs/core/types'\n\nimport type { GoogleDriver } from './drivers/google.js'\nimport type { GithubDriver } from './drivers/github.js'\nimport type { SpotifyDriver } from './drivers/spotify.js'\nimport type { TwitterDriver } from './drivers/twitter.js'\nimport type { DiscordDriver } from './drivers/discord.js'\nimport type { FacebookDriver } from './drivers/facebook.js'\nimport type { LinkedInDriver } from './drivers/linked_in.js'\nimport type { LinkedInOpenidConnectDriver } from './drivers/linked_in_openid_connect.js'\nimport type {\n GoogleDriverConfig,\n GithubDriverConfig,\n SpotifyDriverConfig,\n DiscordDriverConfig,\n TwitterDriverConfig,\n LinkedInDriverConfig,\n LinkedInOpenidConnectDriverConfig,\n FacebookDriverConfig,\n AllyManagerDriverFactory,\n} from './types.js'\n\n/**\n * Shape of config after it has been resolved from\n * the config provider\n */\ntype ResolvedConfig<\n KnownSocialProviders extends Record<\n string,\n AllyManagerDriverFactory | ConfigProvider<AllyManagerDriverFactory>\n >,\n> = {\n [K in keyof KnownSocialProviders]: KnownSocialProviders[K] extends ConfigProvider<infer A>\n ? A\n : KnownSocialProviders[K]\n}\n\n/**\n * Define config for the ally\n */\nexport function defineConfig<\n KnownSocialProviders extends Record<\n string,\n AllyManagerDriverFactory | ConfigProvider<AllyManagerDriverFactory>\n >,\n>(config: KnownSocialProviders): ConfigProvider<ResolvedConfig<KnownSocialProviders>> {\n return configProvider.create(async (app) => {\n const serviceNames = Object.keys(config)\n const services = {} as Record<string, AllyManagerDriverFactory>\n\n for (let serviceName of serviceNames) {\n const service = config[serviceName]\n if (typeof service === 'function') {\n services[serviceName] = service\n } else {\n services[serviceName] = await service.resolver(app)\n }\n }\n\n return services as ResolvedConfig<KnownSocialProviders>\n })\n}\n\n/**\n * Helpers to configure social auth services\n */\nexport const services: {\n discord: (config: DiscordDriverConfig) => ConfigProvider<(ctx: HttpContext) => DiscordDriver>\n facebook: (config: FacebookDriverConfig) => ConfigProvider<(ctx: HttpContext) => FacebookDriver>\n github: (config: GithubDriverConfig) => ConfigProvider<(ctx: HttpContext) => GithubDriver>\n google: (config: GoogleDriverConfig) => ConfigProvider<(ctx: HttpContext) => GoogleDriver>\n linkedin: (config: LinkedInDriverConfig) => ConfigProvider<(ctx: HttpContext) => LinkedInDriver>\n linkedinOpenidConnect: (\n config: LinkedInOpenidConnectDriverConfig\n ) => ConfigProvider<(ctx: HttpContext) => LinkedInOpenidConnectDriver>\n spotify: (config: SpotifyDriverConfig) => ConfigProvider<(ctx: HttpContext) => SpotifyDriver>\n twitter: (config: TwitterDriverConfig) => ConfigProvider<(ctx: HttpContext) => TwitterDriver>\n} = {\n discord(config) {\n return configProvider.create(async () => {\n const { DiscordDriver } = await import('./drivers/discord.js')\n return (ctx) => new DiscordDriver(ctx, config)\n })\n },\n facebook(config) {\n return configProvider.create(async () => {\n const { FacebookDriver } = await import('./drivers/facebook.js')\n return (ctx) => new FacebookDriver(ctx, config)\n })\n },\n github(config) {\n return configProvider.create(async () => {\n const { GithubDriver } = await import('./drivers/github.js')\n return (ctx) => new GithubDriver(ctx, config)\n })\n },\n google(config) {\n return configProvider.create(async () => {\n const { GoogleDriver } = await import('./drivers/google.js')\n return (ctx) => new GoogleDriver(ctx, config)\n })\n },\n linkedin(config) {\n return configProvider.create(async () => {\n const { LinkedInDriver } = await import('./drivers/linked_in.js')\n return (ctx) => new LinkedInDriver(ctx, config)\n })\n },\n linkedinOpenidConnect(config) {\n return configProvider.create(async () => {\n const { LinkedInOpenidConnectDriver } = await import('./drivers/linked_in_openid_connect.js')\n return (ctx) => new LinkedInOpenidConnectDriver(ctx, config)\n })\n },\n spotify(config) {\n return configProvider.create(async () => {\n const { SpotifyDriver } = await import('./drivers/spotify.js')\n return (ctx) => new SpotifyDriver(ctx, config)\n })\n },\n twitter(config) {\n return configProvider.create(async () => {\n const { TwitterDriver } = await import('./drivers/twitter.js')\n return (ctx) => new TwitterDriver(ctx, config)\n })\n },\n}\n"],"mappings":"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","names":["services"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../providers/ally_provider.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { configProvider } from '@adonisjs/core'\nimport { HttpContext } from '@adonisjs/core/http'\nimport { RuntimeException } from '@poppinss/utils'\nimport type { ApplicationService } from '@adonisjs/core/types'\n\nimport type { AllyService } from '../src/types.js'\nimport { AllyManager } from '../src/ally_manager.js'\n\ndeclare module '@adonisjs/core/http' {\n export interface HttpContext {\n ally: AllyService\n }\n}\n\n/**\n * AllyProvider extends the HTTP context with the \"ally\" property\n */\nexport default class AllyProvider {\n constructor(protected app: ApplicationService) {}\n\n async boot() {\n const allyConfigProvider = this.app.config.get<any>('ally')\n\n /**\n * Resolve config from the provider\n */\n const config = await configProvider.resolve<any>(this.app, allyConfigProvider)\n if (!config) {\n throw new RuntimeException(\n 'Invalid \"config/ally.ts\" file. Make sure you are using the \"defineConfig\" method'\n )\n }\n\n /**\n * Setup HTTPContext getter\n */\n HttpContext.getter(\n 'ally',\n function (this: HttpContext) {\n return new AllyManager(config, this) as unknown as AllyService\n },\n true\n )\n }\n}\n"],"mappings":";;;;;;AASA,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AAejC,IAAqB,eAArB,MAAkC;AAAA,EAChC,YAAsB,KAAyB;AAAzB;AAAA,EAA0B;AAAA,EAEhD,MAAM,OAAO;AACX,UAAM,qBAAqB,KAAK,IAAI,OAAO,IAAS,MAAM;AAK1D,UAAM,SAAS,MAAM,eAAe,QAAa,KAAK,KAAK,kBAAkB;AAC7E,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAKA,gBAAY;AAAA,MACV;AAAA,MACA,WAA6B;AAC3B,eAAO,IAAI,YAAY,QAAQ,IAAI;AAAA,MACrC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/drivers/discord.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { HttpClient } from '@poppinss/oauth-client'\n\nimport type {\n DiscordScopes,\n DiscordToken,\n ApiRequestContract,\n DiscordDriverConfig,\n RedirectRequestContract,\n} from '../types.js'\nimport { Oauth2Driver } from '../abstract_drivers/oauth2.js'\n\n/**\n * Discord driver to login user via Discord\n */\nexport class DiscordDriver extends Oauth2Driver<DiscordToken, DiscordScopes> {\n protected accessTokenUrl = 'https://discord.com/api/oauth2/token'\n protected authorizeUrl = 'https://discord.com/oauth2/authorize'\n protected userInfoUrl = 'https://discord.com/api/users/@me'\n\n /**\n * The param name for the authorization code\n */\n protected codeParamName = 'code'\n\n /**\n * The param name for the error\n */\n protected errorParamName = 'error'\n\n /**\n * Cookie name for storing the \"discord_oauth_state\"\n */\n protected stateCookieName = 'discord_oauth_state'\n\n /**\n * Parameter name to be used for sending and receiving the state\n * from Discord\n */\n protected stateParamName = 'state'\n\n /**\n * Parameter name for defining the scopes\n */\n protected scopeParamName = 'scope'\n\n /**\n * Scopes separator\n */\n protected scopesSeparator = ' '\n\n constructor(\n ctx: HttpContext,\n public config: DiscordDriverConfig\n ) {\n super(ctx, config)\n\n /**\n * Extremely important to call the following method to clear the\n * state set by the redirect request\n */\n this.loadState()\n }\n\n /**\n * Configuring the redirect request with defaults\n */\n protected configureRedirectRequest(request: RedirectRequestContract<DiscordScopes>) {\n /**\n * Define user defined scopes or the default one's\n */\n request.scopes(this.config.scopes || ['identify', 'email'])\n\n request.param('response_type', 'code')\n request.param('grant_type', 'authorization_code')\n request.param('integration_type', 1)\n\n /**\n * Define params based upon user config\n */\n if (this.config.prompt) {\n request.param('prompt', this.config.prompt)\n }\n if (this.config.guildId) {\n request.param('guild_id', this.config.guildId)\n }\n if (this.config.disableGuildSelect !== undefined) {\n request.param('disable_guild_select', this.config.disableGuildSelect)\n }\n if (this.config.permissions !== undefined) {\n request.param('permissions', this.config.permissions)\n }\n }\n\n /**\n * Configuring the access token API request to send extra fields\n */\n protected configureAccessTokenRequest(request: ApiRequestContract) {\n /**\n * Send state to Discord when request is not stateles\n */\n if (!this.isStateless) {\n request.field('state', this.stateCookieValue)\n }\n }\n\n /**\n * Returns the HTTP request with the authorization header set\n */\n protected getAuthenticatedRequest(url: string, token: string): HttpClient {\n const request = this.httpClient(url)\n request.header('Authorization', `Bearer ${token}`)\n request.header('Accept', 'application/json')\n request.parseAs('json')\n return request\n }\n\n /**\n * Fetches the user info from the Discord API\n * https://discord.com/developers/docs/resources/user#get-current-user\n */\n protected async getUserInfo(token: string, callback?: (request: ApiRequestContract) => void) {\n const request = this.getAuthenticatedRequest(this.config.userInfoUrl || this.userInfoUrl, token)\n if (typeof callback === 'function') {\n callback(request)\n }\n\n const body = await request.get()\n return {\n id: body.id,\n name: `${body.username}#${body.discriminator}`,\n nickName: body.username,\n avatarUrl: body.avatar\n ? `https://cdn.discordapp.com/avatars/${body.id}/${body.avatar}.${\n body.avatar.startsWith('a_') ? 'gif' : 'png'\n }`\n : `https://cdn.discordapp.com/embed/avatars/${body.discriminator % 5}.png`,\n email: body.email, // May not always be there (requires email scope)\n emailVerificationState:\n 'verified' in body\n ? body.verified\n ? ('verified' as const)\n : ('unverified' as const)\n : ('unsupported' as const),\n original: body,\n }\n }\n\n /**\n * Find if the current error code is for access denied\n */\n accessDenied(): boolean {\n const error = this.getError()\n if (!error) {\n return false\n }\n\n return error === 'access_denied'\n }\n\n /**\n * Returns details for the authorized user\n */\n async user(callback?: (request: ApiRequestContract) => void) {\n const token = await this.accessToken(callback)\n const user = await this.getUserInfo(token.token, callback)\n\n return {\n ...user,\n token,\n }\n }\n\n /**\n * Finds the user by the access token\n */\n async userFromToken(token: string, callback?: (request: ApiRequestContract) => void) {\n const user = await this.getUserInfo(token, callback)\n\n return {\n ...user,\n token: { token, type: 'bearer' as const },\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/drivers/facebook.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type { HttpClient } from '@poppinss/oauth-client'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type {\n FacebookToken,\n FacebookScopes,\n LiteralStringUnion,\n ApiRequestContract,\n FacebookDriverConfig,\n FacebookProfileFields,\n RedirectRequestContract,\n} from '../types.js'\nimport { Oauth2Driver } from '../abstract_drivers/oauth2.js'\n\n/**\n * Facebook driver to login user via Facebook\n */\nexport class FacebookDriver extends Oauth2Driver<FacebookToken, FacebookScopes> {\n protected accessTokenUrl = 'https://graph.facebook.com/v10.0/oauth/access_token'\n protected authorizeUrl = 'https://www.facebook.com/v10.0/dialog/oauth'\n protected userInfoUrl = 'https://graph.facebook.com/v10.0/me'\n\n /**\n * The default set of fields to query for the user request\n */\n protected userFields: LiteralStringUnion<FacebookProfileFields>[] = [\n 'name',\n 'first_name',\n 'last_name',\n 'link',\n 'email',\n 'picture.width(400).height(400)',\n 'verified',\n ]\n\n /**\n * The param name for the authorization code\n */\n protected codeParamName = 'code'\n\n /**\n * The param name for the error\n */\n protected errorParamName = 'error'\n\n /**\n * Cookie name for storing the \"facebok_oauth_state\"\n */\n protected stateCookieName = 'facebok_oauth_state'\n\n /**\n * Parameter name to be used for sending and receiving the state\n * from Facebok\n */\n protected stateParamName = 'state'\n\n /**\n * Parameter name for defining the scopes\n */\n protected scopeParamName = 'scope'\n\n /**\n * Scopes separator\n */\n protected scopesSeparator = ' '\n\n constructor(\n ctx: HttpContext,\n public config: FacebookDriverConfig\n ) {\n super(ctx, config)\n\n /**\n * Extremely important to call the following method to clear the\n * state set by the redirect request\n */\n this.loadState()\n }\n\n /**\n * Configuring the redirect request with defaults\n */\n protected configureRedirectRequest(request: RedirectRequestContract<FacebookScopes>) {\n /**\n * Define user defined scopes or the default one's\n */\n request.scopes(this.config.scopes || ['email'])\n\n request.param('response_type', 'code')\n request.param('grant_type', 'authorization_code')\n\n /**\n * Define params based upon user config\n */\n if (this.config.display) {\n request.param('display', this.config.display)\n }\n if (this.config.authType) {\n request.param('auth_type', this.config.authType)\n }\n }\n\n /**\n * Returns the HTTP request with the authorization header set\n */\n protected getAuthenticatedRequest(url: string, token: string): HttpClient {\n const request = this.httpClient(url)\n request.header('Authorization', `Bearer ${token}`)\n request.header('Accept', 'application/json')\n request.parseAs('json')\n return request\n }\n\n /**\n * Fetches the user info from the Facebook API\n * https://developers.facebook.com/docs/graph-api/reference/user/\n */\n protected async getUserInfo(token: string, callback?: (request: ApiRequestContract) => void) {\n const request = this.getAuthenticatedRequest(this.config.userInfoUrl || this.userInfoUrl, token)\n request.param('fields', (this.config.userFields || this.userFields).join(','))\n\n const body = await request.get()\n\n /**\n * Invoke callback if defined\n */\n if (typeof callback === 'function') {\n callback(request)\n }\n\n return {\n id: body.id,\n name: body.name,\n nickName: body.name,\n // https://developers.facebook.com/docs/graph-api/reference/user/picture/\n avatarUrl: body.picture?.data?.url || null,\n email: body.email || null, // May not always be there (requires email scope)\n // Important note: https://developers.facebook.com/docs/facebook-login/multiple-providers#postfb1\n emailVerificationState:\n 'verified' in body\n ? body.verified\n ? ('verified' as const)\n : ('unverified' as const)\n : ('unsupported' as const),\n original: body,\n }\n }\n\n /**\n * Find if the current error code is for access denied\n */\n accessDenied(): boolean {\n const error = this.getError()\n if (!error) {\n return false\n }\n\n return error === 'access_denied'\n }\n\n /**\n * Returns details for the authorized user\n */\n async user(callback?: (request: ApiRequestContract) => void) {\n const token = await this.accessToken(callback)\n const user = await this.getUserInfo(token.token, callback)\n\n return {\n ...user,\n token,\n }\n }\n\n /**\n * Finds the user by the access token\n */\n async userFromToken(token: string, callback?: (request: ApiRequestContract) => void) {\n const user = await this.getUserInfo(token, callback)\n\n return {\n ...user,\n token: { token, type: 'bearer' as const },\n }\n }\n}\n"],"mappings":";;;;;;;AAyBO,IAAM,iBAAN,cAA6B,aAA4C;AAAA,EAiD9E,YACE,KACO,QACP;AACA,UAAM,KAAK,MAAM;AAFV;AAQP,SAAK,UAAU;AAAA,EACjB;AAAA,EA3DU,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,cAAc;AAAA;AAAA;AAAA;AAAA,EAKd,aAA0D;AAAA,IAClE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKU,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAKhB,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAKjB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAKjB,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAKjB,kBAAkB;AAAA;AAAA;AAAA;AAAA,EAkBlB,yBAAyB,SAAkD;AAInF,YAAQ,OAAO,KAAK,OAAO,UAAU,CAAC,OAAO,CAAC;AAE9C,YAAQ,MAAM,iBAAiB,MAAM;AACrC,YAAQ,MAAM,cAAc,oBAAoB;AAKhD,QAAI,KAAK,OAAO,SAAS;AACvB,cAAQ,MAAM,WAAW,KAAK,OAAO,OAAO;AAAA,IAC9C;AACA,QAAI,KAAK,OAAO,UAAU;AACxB,cAAQ,MAAM,aAAa,KAAK,OAAO,QAAQ;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKU,wBAAwB,KAAa,OAA2B;AACxE,UAAM,UAAU,KAAK,WAAW,GAAG;AACnC,YAAQ,OAAO,iBAAiB,UAAU,KAAK,EAAE;AACjD,YAAQ,OAAO,UAAU,kBAAkB;AAC3C,YAAQ,QAAQ,MAAM;AACtB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,YAAY,OAAe,UAAkD;AAC3F,UAAM,UAAU,KAAK,wBAAwB,KAAK,OAAO,eAAe,KAAK,aAAa,KAAK;AAC/F,YAAQ,MAAM,WAAW,KAAK,OAAO,cAAc,KAAK,YAAY,KAAK,GAAG,CAAC;AAE7E,UAAM,OAAO,MAAM,QAAQ,IAAI;AAK/B,QAAI,OAAO,aAAa,YAAY;AAClC,eAAS,OAAO;AAAA,IAClB;AAEA,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA;AAAA,MAEf,WAAW,KAAK,SAAS,MAAM,OAAO;AAAA,MACtC,OAAO,KAAK,SAAS;AAAA;AAAA;AAAA,MAErB,wBACE,cAAc,OACV,KAAK,WACF,aACA,eACF;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAwB;AACtB,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,WAAO,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,UAAkD;AAC3D,UAAM,QAAQ,MAAM,KAAK,YAAY,QAAQ;AAC7C,UAAM,OAAO,MAAM,KAAK,YAAY,MAAM,OAAO,QAAQ;AAEzD,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,OAAe,UAAkD;AACnF,UAAM,OAAO,MAAM,KAAK,YAAY,OAAO,QAAQ;AAEnD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,EAAE,OAAO,MAAM,SAAkB;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/drivers/github.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { HttpClient } from '@poppinss/oauth-client'\nimport type {\n GithubToken,\n GithubScopes,\n AllyUserContract,\n GithubDriverConfig,\n ApiRequestContract,\n RedirectRequestContract,\n} from '../types.js'\nimport { Oauth2Driver } from '../abstract_drivers/oauth2.js'\n\n/**\n * Github driver to login user via Github\n */\nexport class GithubDriver extends Oauth2Driver<GithubToken, GithubScopes> {\n protected accessTokenUrl = 'https://github.com/login/oauth/access_token'\n protected authorizeUrl = 'https://github.com/login/oauth/authorize'\n protected userInfoUrl = 'https://api.github.com/user'\n protected userEmailUrl = 'https://api.github.com/user/emails'\n\n /**\n * The param name for the authorization code\n */\n protected codeParamName = 'code'\n\n /**\n * The param name for the error\n */\n protected errorParamName = 'error'\n\n /**\n * Cookie name for storing the \"gh_oauth_state\"\n */\n protected stateCookieName = 'gh_oauth_state'\n\n /**\n * Parameter name to be used for sending and receiving the state\n * from Github\n */\n protected stateParamName = 'state'\n\n /**\n * Parameter name for defining the scopes\n */\n protected scopeParamName = 'scope'\n\n /**\n * Scopes separator\n */\n protected scopesSeparator = ' '\n\n constructor(\n ctx: HttpContext,\n public config: GithubDriverConfig\n ) {\n super(ctx, config)\n /**\n * Extremely important to call the following method to clear the\n * state set by the redirect request\n */\n this.loadState()\n }\n\n /**\n * Configuring the redirect request with defaults\n */\n protected configureRedirectRequest(request: RedirectRequestContract<GithubScopes>) {\n /**\n * Define user defined scopes or the default one's\n */\n request.scopes(this.config.scopes || ['user'])\n\n /**\n * Set \"allow_signup\" option when defined\n */\n if (this.config.allowSignup !== undefined) {\n request.param('allow_signup', this.config.allowSignup)\n }\n\n /**\n * Set \"login\" option when defined\n */\n if (this.config.login) {\n request.param('login', this.config.login)\n }\n }\n\n /**\n * Configuring the access token API request to send extra fields\n */\n protected configureAccessTokenRequest(request: ApiRequestContract) {\n /**\n * Send state to github when request is not stateles\n */\n if (!this.isStateless) {\n request.field('state', this.stateCookieValue)\n }\n\n /**\n * Clearing the default defined \"grant_type\". Github doesn't accept this.\n * https://github.com/poppinss/oauth-client#following-is-the-list-of-fieldsparams-set-by-the-clients-implicitly\n */\n request.clearField('grant_type')\n }\n\n /**\n * Returns the HTTP request with the authorization header set\n */\n protected getAuthenticatedRequest(url: string, token: string): HttpClient {\n const request = this.httpClient(url)\n request.header('Authorization', `token ${token}`)\n request.header('Accept', 'application/json')\n request.parseAs('json')\n return request\n }\n\n /**\n * Fetches the user info from the Github API\n * https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\n */\n protected async getUserInfo(token: string, callback?: (request: ApiRequestContract) => void) {\n const request = this.getAuthenticatedRequest(this.config.userInfoUrl || this.userInfoUrl, token)\n if (typeof callback === 'function') {\n callback(request)\n }\n\n const body = await request.get()\n return {\n id: body.id,\n nickName: body.name,\n email: body.email, // May not always be there\n emailVerificationState: (body.email\n ? 'verified'\n : 'unsupported') as AllyUserContract<any>['emailVerificationState'],\n name: body.name ?? body.login,\n avatarUrl: body.avatar_url,\n original: body,\n }\n }\n\n /**\n * Fetches the user email from the Github API.\n * https://docs.github.com/en/rest/reference/users#list-email-addresses-for-the-authenticated-user\n */\n protected async getUserEmail(token: string, callback?: (request: ApiRequestContract) => void) {\n const request = this.getAuthenticatedRequest(\n this.config.userEmailUrl || this.userEmailUrl,\n token\n )\n\n if (typeof callback === 'function') {\n callback(request)\n }\n\n try {\n let emails = await request.get()\n\n /**\n * Sort emails to keep the primary ones on the top\n */\n emails = emails.sort((email: any) => (email.primary ? -1 : 1))\n\n /**\n * Get the first verified email of the user\n */\n let mainEmail = emails.find((email: any) => email.verified)\n\n /**\n * If there are no verified emails, then get any first one\n */\n if (!mainEmail) {\n mainEmail = emails[0]\n }\n\n return mainEmail\n } catch (error) {\n if (error && error.response && error.response.statusCode === 404) {\n return\n }\n throw error\n }\n }\n\n /**\n * Find if the current error code is for access denied\n */\n accessDenied(): boolean {\n const error = this.getError()\n if (!error) {\n return false\n }\n\n return error === 'access_denied'\n }\n\n /**\n * Returns details for the authorized user\n */\n async user(callback?: (request: ApiRequestContract) => void) {\n const token = await this.accessToken(callback)\n const user = await this.getUserInfo(token.token, callback)\n\n /**\n * Fetch email separately\n */\n if (!user.email) {\n this.ctx.logger.trace('Fetching github user email separately')\n\n const emailResponse = await this.getUserEmail(token.token, callback)\n if (emailResponse) {\n user.email = emailResponse.email\n user.emailVerificationState = emailResponse.verified\n ? ('verified' as const)\n : ('unverified' as const)\n }\n }\n\n return {\n ...user,\n token: token,\n }\n }\n\n /**\n * Finds the user by the access token\n */\n async userFromToken(token: string, callback?: (request: ApiRequestContract) => void) {\n const user = await this.getUserInfo(token, callback)\n\n /**\n * Fetch email separately\n */\n if (!user.email) {\n this.ctx.logger.trace('Fetching github user email separately')\n\n const emailResponse = await this.getUserEmail(token, callback)\n if (emailResponse) {\n user.email = emailResponse.email\n user.emailVerificationState = emailResponse.verified\n ? ('verified' as const)\n : ('unverified' as const)\n }\n }\n\n return {\n ...user,\n token: { token, type: 'bearer' as const },\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/drivers/google.ts"],"sourcesContent":["/*\n * @adonisjs/ally\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { HttpClient } from '@poppinss/oauth-client'\nimport type {\n GoogleToken,\n GoogleScopes,\n GoogleDriverConfig,\n ApiRequestContract,\n RedirectRequestContract,\n} from '../types.js'\nimport { Oauth2Driver } from '../abstract_drivers/oauth2.js'\n\nconst SCOPE_PREFIXES = {\n 'https://www.googleapis.com/auth': [\n 'userinfo.email',\n 'userinfo.profile',\n 'contacts',\n 'contacts.other.readonly',\n 'contacts.readonly',\n 'directory.readonly',\n 'user.addresses.read',\n 'user.birthday.read',\n 'user.emails.read',\n 'user.gender.read',\n 'user.organization.read',\n 'user.phonenumbers.read',\n 'analytics',\n 'analytics.readonly',\n 'documents',\n 'documents.readonly',\n 'forms',\n 'forms.currentonly',\n 'groups',\n 'spreadsheets',\n 'calendar',\n 'calendar.events',\n 'calendar.events.readonly',\n 'calendar.readonly',\n 'calendar.settings.readonly',\n 'drive',\n 'drive.appdata',\n 'drive.file',\n 'drive.metadata',\n 'drive.metadata.readonly',\n 'drive.photos.readonly',\n 'drive.readonly',\n 'drive.scripts',\n ],\n}\n\n/**\n * Google driver to login user via Google\n */\nexport class GoogleDriver extends Oauth2Driver<GoogleToken, GoogleScopes> {\n protected accessTokenUrl = 'https://oauth2.googleapis.com/token'\n protected authorizeUrl = 'https://accounts.google.com/o/oauth2/v2/auth'\n protected userInfoUrl = 'https://www.googleapis.com/oauth2/v3/userinfo'\n\n /**\n * The param name for the authorization code\n */\n protected codeParamName = 'code'\n\n /**\n * The param name for the error\n */\n protected errorParamName = 'error'\n\n /**\n * Cookie name for storing the \"google_oauth_state\"\n */\n protected stateCookieName = 'google_oauth_state'\n\n /**\n * Parameter name to be used for sending and receiving the state\n * from google\n */\n protected stateParamName = 'state'\n\n /**\n * Parameter name for defining the scopes\n */\n protected scopeParamName = 'scope'\n\n /**\n * Scopes separator\n */\n protected scopesSeparator = ' '\n\n constructor(\n ctx: HttpContext,\n public config: GoogleDriverConfig\n ) {\n super(ctx, config)\n /**\n * Extremely important to call the following method to clear the\n * state set by the redirect request\n */\n this.loadState()\n }\n\n /**\n * Configuring the redirect request with defaults\n */\n protected configureRedirectRequest(request: RedirectRequestContract<GoogleScopes>) {\n request.transformScopes((scopes) => this.buildScopes(scopes))\n\n /**\n * Define user defined scopes or the default one's\n */\n request.scopes(this.config.scopes || ['openid', 'userinfo.email', 'userinfo.profile'])\n\n /**\n * Set \"response_type\" param\n */\n request.param('response_type', 'code')\n\n /**\n * Define params based upon user config\n */\n if (this.config.accessType) {\n request.param('access_type', this.config.accessType)\n }\n if (this.config.prompt) {\n request.param('prompt', this.config.prompt)\n }\n if (this.config.display) {\n request.param('display', this.config.display)\n }\n if (this.config.hostedDomain) {\n request.param('hd', this.config.hostedDomain)\n }\n }\n\n /**\n * Returns the HTTP request with the authorization header set\n */\n protected getAuthenticatedRequest(url: string, token: string): HttpClient {\n const request = this.httpClient(url)\n request.header('Authorization', `Bearer ${token}`)\n request.header('Accept', 'application/json')\n request.parseAs('json')\n return request\n }\n\n /**\n * Fetches the user info from the Google API\n */\n protected async getUserInfo(token: string, callback?: (request: ApiRequestContract) => void) {\n const request = this.getAuthenticatedRequest(this.config.userInfoUrl || this.userInfoUrl, token)\n if (typeof callback === 'function') {\n callback(request)\n }\n\n const body = await request.get()\n\n return {\n id: body.sub,\n nickName: body.name,\n name: body.name,\n email: body.email,\n avatarUrl: body.picture,\n emailVerificationState: body.email_verified ? ('verified' as const) : ('unverified' as const),\n original: body,\n }\n }\n\n /**\n * Find if the current error code is for access denied\n */\n accessDenied(): boolean {\n const error = this.getError()\n if (!error) {\n return false\n }\n\n return error === 'access_denied'\n }\n\n /**\n * Get access token\n */\n async accessToken(callback?: (request: ApiRequestContract) => void): Promise<GoogleToken> {\n const token = await super.accessToken(callback)\n\n return {\n ...token,\n idToken: token.id_token,\n }\n }\n\n /**\n * Returns details for the authorized user\n */\n async user(callback?: (request: ApiRequestContract) => void) {\n const token = await this.accessToken(callback)\n const user = await this.getUserInfo(token.token, callback)\n\n return {\n ...user,\n token: token,\n }\n }\n\n /**\n * Finds the user by the access token\n */\n async userFromToken(token: string, callback?: (request: ApiRequestContract) => void) {\n const user = await this.getUserInfo(token, callback)\n\n return {\n ...user,\n token: { token, type: 'bearer' as const },\n }\n }\n\n /**\n * Prefixes google scopes with the url\n */\n buildScopes(scopes: string[]) {\n return scopes.map((name) => {\n const prefix = Object.keys(SCOPE_PREFIXES).find((one) =>\n SCOPE_PREFIXES[one as keyof typeof SCOPE_PREFIXES].includes(name)\n )\n return prefix ? `${prefix}/${name}` : name\n })\n }\n}\n"],"mappings":"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","names":[]}
|