@adonisjs/auth 8.0.11 → 8.2.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/adonis-typings/auth.d.ts +51 -1
- package/build/adonis-typings/index.d.ts +1 -0
- package/build/adonis-typings/index.js +1 -0
- package/build/adonis-typings/tests.d.ts +23 -0
- package/build/adonis-typings/tests.js +11 -0
- package/build/providers/AuthProvider.d.ts +12 -0
- package/build/providers/AuthProvider.js +24 -2
- package/build/src/AuthManager/index.d.ts +30 -4
- package/build/src/AuthManager/index.js +65 -0
- package/build/src/Bindings/Tests.d.ts +6 -0
- package/build/src/Bindings/Tests.js +69 -0
- package/build/src/Clients/Oat/index.d.ts +50 -0
- package/build/src/Clients/Oat/index.js +123 -0
- package/build/src/Clients/Session/index.d.ts +34 -0
- package/build/src/Clients/Session/index.js +72 -0
- package/build/src/TokenProviders/Database/index.js +2 -2
- package/package.json +40 -36
|
@@ -230,6 +230,28 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
230
230
|
default: DatabaseProviderUserBuilder;
|
|
231
231
|
}>;
|
|
232
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* Request data a guard client can set when making the
|
|
235
|
+
* testing request
|
|
236
|
+
*/
|
|
237
|
+
export type ClientRequestData = {
|
|
238
|
+
session?: Record<string, any>;
|
|
239
|
+
headers?: Record<string, any>;
|
|
240
|
+
cookies?: Record<string, any>;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* The authentication clients should follow this interface
|
|
244
|
+
*/
|
|
245
|
+
export interface GuardClientContract<Provider extends keyof ProvidersList> {
|
|
246
|
+
/**
|
|
247
|
+
* Login a user
|
|
248
|
+
*/
|
|
249
|
+
login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<ClientRequestData>;
|
|
250
|
+
/**
|
|
251
|
+
* Logout user
|
|
252
|
+
*/
|
|
253
|
+
logout(user: GetProviderRealUser<Provider>): Promise<void>;
|
|
254
|
+
}
|
|
233
255
|
export interface GuardContract<Provider extends keyof ProvidersList, Guard extends keyof GuardsList> {
|
|
234
256
|
name: Guard;
|
|
235
257
|
/**
|
|
@@ -345,6 +367,11 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
345
367
|
*/
|
|
346
368
|
logout(renewRememberToken?: boolean): Promise<void>;
|
|
347
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Session client to login users during tests
|
|
372
|
+
*/
|
|
373
|
+
export interface SessionClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
|
|
374
|
+
}
|
|
348
375
|
/**
|
|
349
376
|
* Shape of session driver config.
|
|
350
377
|
*/
|
|
@@ -365,6 +392,11 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
365
392
|
*/
|
|
366
393
|
export interface BasicAuthGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends Omit<GuardContract<Provider, Name>, 'attempt' | 'login' | 'loginViaId' | 'logout'> {
|
|
367
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Basic auth client to login users during tests
|
|
397
|
+
*/
|
|
398
|
+
export interface BasicAuthClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
|
|
399
|
+
}
|
|
368
400
|
/**
|
|
369
401
|
* Shape of basic auth guard config.
|
|
370
402
|
*/
|
|
@@ -473,6 +505,12 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
473
505
|
*/
|
|
474
506
|
loginViaId(id: string | number, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
|
|
475
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* Oat guard to login users during tests
|
|
510
|
+
*/
|
|
511
|
+
export interface OATClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
|
|
512
|
+
login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<ClientRequestData>;
|
|
513
|
+
}
|
|
476
514
|
/**
|
|
477
515
|
* Shape of OAT guard config.
|
|
478
516
|
*/
|
|
@@ -517,6 +555,7 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
517
555
|
* session: {
|
|
518
556
|
* config: SessionGuardConfig<'lucid'>,
|
|
519
557
|
* implementation: SessionGuardContract<'lucid'>,
|
|
558
|
+
* client: SessionClientContract<'lucid'>,
|
|
520
559
|
* }
|
|
521
560
|
*
|
|
522
561
|
*/
|
|
@@ -555,6 +594,11 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
555
594
|
* Shape of the callback accepted to add new guards
|
|
556
595
|
*/
|
|
557
596
|
export type ExtendGuardCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>, ctx: HttpContextContract) => GuardContract<keyof ProvidersList, keyof GuardsList>;
|
|
597
|
+
/**
|
|
598
|
+
* Shape of the callback accepted to add custom testing
|
|
599
|
+
* clients
|
|
600
|
+
*/
|
|
601
|
+
export type ExtendClientCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>) => GuardClientContract<keyof ProvidersList>;
|
|
558
602
|
/**
|
|
559
603
|
* Shape of the auth manager to register custom drivers and providers and
|
|
560
604
|
* make instances of them
|
|
@@ -575,10 +619,16 @@ declare module '@ioc:Adonis/Addons/Auth' {
|
|
|
575
619
|
makeMapping(ctx: HttpContextContract, mapping: string): GuardContract<keyof ProvidersList, keyof GuardsList>;
|
|
576
620
|
makeMapping<K extends keyof GuardsList>(ctx: HttpContextContract, mapping: K): GuardsList[K]['implementation'];
|
|
577
621
|
/**
|
|
578
|
-
*
|
|
622
|
+
* Returns an instance of the auth client for a given
|
|
623
|
+
* mapping
|
|
624
|
+
*/
|
|
625
|
+
client(mapping: string): GuardClientContract<keyof ProvidersList>;
|
|
626
|
+
/**
|
|
627
|
+
* Extend by adding custom providers, guards and client
|
|
579
628
|
*/
|
|
580
629
|
extend(type: 'provider', provider: string, callback: ExtendProviderCallback): void;
|
|
581
630
|
extend(type: 'guard', guard: string, callback: ExtendGuardCallback): void;
|
|
631
|
+
extend(type: 'client', guard: string, callback: ExtendClientCallback): void;
|
|
582
632
|
}
|
|
583
633
|
const AuthManager: AuthManagerContract;
|
|
584
634
|
export default AuthManager;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import '@japa/api-client';
|
|
2
|
+
import { GuardsList, ProvidersList, AuthManagerContract, GetProviderRealUser } from '@ioc:Adonis/Addons/Auth';
|
|
3
|
+
declare module '@japa/api-client' {
|
|
4
|
+
interface ApiRequest {
|
|
5
|
+
/**
|
|
6
|
+
* Auth manager reference
|
|
7
|
+
*/
|
|
8
|
+
authManager: AuthManagerContract;
|
|
9
|
+
/**
|
|
10
|
+
* Switch guard to login during the request
|
|
11
|
+
*/
|
|
12
|
+
guard<K extends keyof GuardsList, Self>(this: Self, guard: K): {
|
|
13
|
+
/**
|
|
14
|
+
* Login as a user
|
|
15
|
+
*/
|
|
16
|
+
loginAs(...args: Parameters<GuardsList[K]['client']['login']>): Self;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Login as a user
|
|
20
|
+
*/
|
|
21
|
+
loginAs(user: GetProviderRealUser<keyof ProvidersList>): this;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* @adonisjs/auth
|
|
4
|
+
*
|
|
5
|
+
* (c) AdonisJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
require("@japa/api-client");
|
|
@@ -11,6 +11,18 @@ export default class AuthProvider {
|
|
|
11
11
|
* Register auth binding
|
|
12
12
|
*/
|
|
13
13
|
register(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Sharing the auth object with HTTP context
|
|
16
|
+
*/
|
|
17
|
+
protected registerAuthWithHttpContext(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Sharing auth with all the templates
|
|
20
|
+
*/
|
|
21
|
+
protected shareAuthWithViews(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Register test bindings
|
|
24
|
+
*/
|
|
25
|
+
protected registerTestBindings(): void;
|
|
14
26
|
/**
|
|
15
27
|
* Hook into boot to register auth macro
|
|
16
28
|
*/
|
|
@@ -28,20 +28,42 @@ class AuthProvider {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Sharing the auth object with HTTP context
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
registerAuthWithHttpContext() {
|
|
34
34
|
this.application.container.withBindings(['Adonis/Core/HttpContext', 'Adonis/Addons/Auth'], (HttpContext, Auth) => {
|
|
35
35
|
HttpContext.getter('auth', function auth() {
|
|
36
36
|
return Auth.getAuthForRequest(this);
|
|
37
37
|
}, true);
|
|
38
38
|
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Sharing auth with all the templates
|
|
42
|
+
*/
|
|
43
|
+
shareAuthWithViews() {
|
|
39
44
|
this.application.container.withBindings(['Adonis/Core/Server', 'Adonis/Core/View'], (Server) => {
|
|
40
45
|
Server.hooks.before(async (ctx) => {
|
|
41
46
|
ctx['view'].share({ auth: ctx.auth });
|
|
42
47
|
});
|
|
43
48
|
});
|
|
44
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Register test bindings
|
|
52
|
+
*/
|
|
53
|
+
registerTestBindings() {
|
|
54
|
+
this.application.container.withBindings(['Japa/Preset/ApiRequest', 'Japa/Preset/ApiClient', 'Adonis/Addons/Auth'], (ApiRequest, ApiClient, Auth) => {
|
|
55
|
+
const { defineTestsBindings } = require('../src/Bindings/Tests');
|
|
56
|
+
return defineTestsBindings(ApiRequest, ApiClient, Auth);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Hook into boot to register auth macro
|
|
61
|
+
*/
|
|
62
|
+
async boot() {
|
|
63
|
+
this.registerAuthWithHttpContext();
|
|
64
|
+
this.shareAuthWithViews();
|
|
65
|
+
this.registerTestBindings();
|
|
66
|
+
}
|
|
45
67
|
}
|
|
46
68
|
exports.default = AuthProvider;
|
|
47
69
|
AuthProvider.needsApplication = true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@adonisjs/application/build/adonis-typings/application" />
|
|
2
|
-
import { AuthConfig, GuardsList, AuthManagerContract, ExtendGuardCallback,
|
|
2
|
+
import { AuthConfig, GuardsList, AuthManagerContract, ExtendGuardCallback, ExtendProviderCallback, ExtendClientCallback } from '@ioc:Adonis/Addons/Auth';
|
|
3
3
|
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
|
|
4
4
|
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
|
5
5
|
/**
|
|
@@ -9,6 +9,10 @@ import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
|
|
9
9
|
export declare class AuthManager implements AuthManagerContract {
|
|
10
10
|
application: ApplicationContract;
|
|
11
11
|
private config;
|
|
12
|
+
/**
|
|
13
|
+
* Extended set of testing clients
|
|
14
|
+
*/
|
|
15
|
+
private extendedClients;
|
|
12
16
|
/**
|
|
13
17
|
* Extended set of providers
|
|
14
18
|
*/
|
|
@@ -62,23 +66,44 @@ export declare class AuthManager implements AuthManagerContract {
|
|
|
62
66
|
* Returns an instance of the extended guard
|
|
63
67
|
*/
|
|
64
68
|
private makeExtendedGuard;
|
|
69
|
+
/**
|
|
70
|
+
* Returns an instance of the session client
|
|
71
|
+
*/
|
|
72
|
+
private makeSessionClient;
|
|
73
|
+
/**
|
|
74
|
+
* Returns an instance of the session client
|
|
75
|
+
*/
|
|
76
|
+
private makeOatClient;
|
|
77
|
+
/**
|
|
78
|
+
* Returns an instance of the extended client
|
|
79
|
+
*/
|
|
80
|
+
private makeExtendedClient;
|
|
81
|
+
/**
|
|
82
|
+
* Makes client instance for the defined driver inside the
|
|
83
|
+
* mapping config.
|
|
84
|
+
*/
|
|
85
|
+
private makeClientInstance;
|
|
65
86
|
/**
|
|
66
87
|
* Makes instance of a provider based upon the driver value
|
|
67
88
|
*/
|
|
68
|
-
makeUserProviderInstance
|
|
89
|
+
private makeUserProviderInstance;
|
|
69
90
|
/**
|
|
70
91
|
* Makes instance of a provider based upon the driver value
|
|
71
92
|
*/
|
|
72
|
-
makeTokenProviderInstance
|
|
93
|
+
private makeTokenProviderInstance;
|
|
73
94
|
/**
|
|
74
95
|
* Makes guard instance for the defined driver inside the
|
|
75
96
|
* mapping config.
|
|
76
97
|
*/
|
|
77
|
-
makeGuardInstance
|
|
98
|
+
private makeGuardInstance;
|
|
78
99
|
/**
|
|
79
100
|
* Make an instance of a given mapping for the current HTTP request.
|
|
80
101
|
*/
|
|
81
102
|
makeMapping(ctx: HttpContextContract, mapping: keyof GuardsList): any;
|
|
103
|
+
/**
|
|
104
|
+
* Returns an instance of the testing
|
|
105
|
+
*/
|
|
106
|
+
client(mapping: keyof GuardsList): any;
|
|
82
107
|
/**
|
|
83
108
|
* Returns an instance of the auth class for the current request
|
|
84
109
|
*/
|
|
@@ -88,4 +113,5 @@ export declare class AuthManager implements AuthManagerContract {
|
|
|
88
113
|
*/
|
|
89
114
|
extend(type: 'provider', name: string, callback: ExtendProviderCallback): void;
|
|
90
115
|
extend(type: 'guard', name: string, callback: ExtendGuardCallback): void;
|
|
116
|
+
extend(type: 'client', name: string, callback: ExtendClientCallback): void;
|
|
91
117
|
}
|
|
@@ -19,6 +19,10 @@ class AuthManager {
|
|
|
19
19
|
constructor(application, config) {
|
|
20
20
|
this.application = application;
|
|
21
21
|
this.config = config;
|
|
22
|
+
/**
|
|
23
|
+
* Extended set of testing clients
|
|
24
|
+
*/
|
|
25
|
+
this.extendedClients = new Map();
|
|
22
26
|
/**
|
|
23
27
|
* Extended set of providers
|
|
24
28
|
*/
|
|
@@ -117,6 +121,50 @@ class AuthManager {
|
|
|
117
121
|
}
|
|
118
122
|
return guardCallback(this, mapping, config, provider, ctx);
|
|
119
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Returns an instance of the session client
|
|
126
|
+
*/
|
|
127
|
+
makeSessionClient(mapping, config, provider) {
|
|
128
|
+
const { SessionClient } = require('../Clients/Session');
|
|
129
|
+
return new SessionClient(mapping, config, provider);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns an instance of the session client
|
|
133
|
+
*/
|
|
134
|
+
makeOatClient(mapping, config, provider) {
|
|
135
|
+
const { OATClient } = require('../Clients/Oat');
|
|
136
|
+
const tokenProvider = this.makeTokenProviderInstance(config.tokenProvider);
|
|
137
|
+
return new OATClient(mapping, config, provider, tokenProvider);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Returns an instance of the extended client
|
|
141
|
+
*/
|
|
142
|
+
makeExtendedClient(mapping, config, provider) {
|
|
143
|
+
const clientCallback = this.extendedClients.get(config.driver);
|
|
144
|
+
if (!clientCallback) {
|
|
145
|
+
throw new utils_1.Exception(`Invalid guard driver "${config.driver}" property`);
|
|
146
|
+
}
|
|
147
|
+
return clientCallback(this, mapping, config, provider);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Makes client instance for the defined driver inside the
|
|
151
|
+
* mapping config.
|
|
152
|
+
*/
|
|
153
|
+
makeClientInstance(mapping, mappingConfig, provider) {
|
|
154
|
+
if (!mappingConfig || !mappingConfig.driver) {
|
|
155
|
+
throw new utils_1.Exception('Invalid auth config, missing "driver" property');
|
|
156
|
+
}
|
|
157
|
+
switch (mappingConfig.driver) {
|
|
158
|
+
case 'session':
|
|
159
|
+
return this.makeSessionClient(mapping, mappingConfig, provider);
|
|
160
|
+
case 'oat':
|
|
161
|
+
return this.makeOatClient(mapping, mappingConfig, provider);
|
|
162
|
+
case 'basic':
|
|
163
|
+
throw new utils_1.Exception('There is no testing client for basic auth. Use "request.basicAuth" method instead');
|
|
164
|
+
default:
|
|
165
|
+
return this.makeExtendedClient(mapping, mappingConfig, provider);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
120
168
|
/**
|
|
121
169
|
* Makes instance of a provider based upon the driver value
|
|
122
170
|
*/
|
|
@@ -179,6 +227,17 @@ class AuthManager {
|
|
|
179
227
|
const provider = this.makeUserProviderInstance(mapping, mappingConfig.provider);
|
|
180
228
|
return this.makeGuardInstance(mapping, mappingConfig, provider, ctx);
|
|
181
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns an instance of the testing
|
|
232
|
+
*/
|
|
233
|
+
client(mapping) {
|
|
234
|
+
const mappingConfig = this.config.guards[mapping];
|
|
235
|
+
if (mappingConfig === undefined) {
|
|
236
|
+
throw new utils_1.Exception(`Invalid guard "${mapping}". Make sure the guard is defined inside the config/auth file`);
|
|
237
|
+
}
|
|
238
|
+
const provider = this.makeUserProviderInstance(mapping, mappingConfig.provider);
|
|
239
|
+
return this.makeClientInstance(mapping, mappingConfig, provider);
|
|
240
|
+
}
|
|
182
241
|
/**
|
|
183
242
|
* Returns an instance of the auth class for the current request
|
|
184
243
|
*/
|
|
@@ -188,9 +247,15 @@ class AuthManager {
|
|
|
188
247
|
extend(type, name, callback) {
|
|
189
248
|
if (type === 'provider') {
|
|
190
249
|
this.extendedProviders.set(name, callback);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (type === 'client') {
|
|
253
|
+
this.extendedClients.set(name, callback);
|
|
254
|
+
return;
|
|
191
255
|
}
|
|
192
256
|
if (type === 'guard') {
|
|
193
257
|
this.extendedGuards.set(name, callback);
|
|
258
|
+
return;
|
|
194
259
|
}
|
|
195
260
|
}
|
|
196
261
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AuthManagerContract } from '@ioc:Adonis/Addons/Auth';
|
|
2
|
+
import { ContainerBindings } from '@ioc:Adonis/Core/Application';
|
|
3
|
+
/**
|
|
4
|
+
* Define test bindings
|
|
5
|
+
*/
|
|
6
|
+
export declare function defineTestsBindings(ApiRequest: ContainerBindings['Japa/Preset/ApiRequest'], ApiClient: ContainerBindings['Japa/Preset/ApiClient'], AuthManager: AuthManagerContract): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* @adonisjs/auth
|
|
4
|
+
*
|
|
5
|
+
* (c) AdonisJS Auth
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.defineTestsBindings = void 0;
|
|
12
|
+
/**
|
|
13
|
+
* Define test bindings
|
|
14
|
+
*/
|
|
15
|
+
function defineTestsBindings(ApiRequest, ApiClient, AuthManager) {
|
|
16
|
+
/**
|
|
17
|
+
* Set "sessionClient" on the api request
|
|
18
|
+
*/
|
|
19
|
+
ApiRequest.getter('authManager', function () {
|
|
20
|
+
return AuthManager;
|
|
21
|
+
}, true);
|
|
22
|
+
/**
|
|
23
|
+
* Login user using the default guard
|
|
24
|
+
*/
|
|
25
|
+
ApiRequest.macro('loginAs', function (user) {
|
|
26
|
+
this['authData'] = {
|
|
27
|
+
client: this.authManager.client(this.authManager.defaultGuard),
|
|
28
|
+
args: [user],
|
|
29
|
+
};
|
|
30
|
+
return this;
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Login user using a custom guard
|
|
34
|
+
*/
|
|
35
|
+
ApiRequest.macro('guard', function (mapping) {
|
|
36
|
+
return {
|
|
37
|
+
loginAs: (...args) => {
|
|
38
|
+
this['authData'] = {
|
|
39
|
+
client: this.authManager.client(mapping),
|
|
40
|
+
args,
|
|
41
|
+
};
|
|
42
|
+
return this;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Hook into the request and login the user
|
|
48
|
+
*/
|
|
49
|
+
ApiClient.setup(async (request) => {
|
|
50
|
+
const authData = request['authData'];
|
|
51
|
+
if (!authData) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const requestData = await authData.client.login(...authData.args);
|
|
55
|
+
if (requestData.headers) {
|
|
56
|
+
request.headers(requestData.headers);
|
|
57
|
+
}
|
|
58
|
+
if (requestData.session) {
|
|
59
|
+
request.session(requestData.session);
|
|
60
|
+
}
|
|
61
|
+
if (requestData.cookies) {
|
|
62
|
+
request.cookies(requestData.cookies);
|
|
63
|
+
}
|
|
64
|
+
return async () => {
|
|
65
|
+
await authData.client.logout(...authData.args);
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
exports.defineTestsBindings = defineTestsBindings;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { OATGuardConfig, OATLoginOptions, OATClientContract, UserProviderContract, ClientRequestData } from '@ioc:Adonis/Addons/Auth';
|
|
2
|
+
import { TokenProviderContract } from '@ioc:Adonis/Addons/Auth';
|
|
3
|
+
/**
|
|
4
|
+
* OAT client to login a user during tests using the
|
|
5
|
+
* opaque tokens guard
|
|
6
|
+
*/
|
|
7
|
+
export declare class OATClient implements OATClientContract<any> {
|
|
8
|
+
name: string;
|
|
9
|
+
config: OATGuardConfig<any>;
|
|
10
|
+
private provider;
|
|
11
|
+
tokenProvider: TokenProviderContract;
|
|
12
|
+
constructor(name: string, config: OATGuardConfig<any>, provider: UserProviderContract<any>, tokenProvider: TokenProviderContract);
|
|
13
|
+
/**
|
|
14
|
+
* Token generated during the login call
|
|
15
|
+
*/
|
|
16
|
+
private tokenId?;
|
|
17
|
+
/**
|
|
18
|
+
* Length of the raw token. The hash length will vary
|
|
19
|
+
*/
|
|
20
|
+
private tokenLength;
|
|
21
|
+
/**
|
|
22
|
+
* Token type for the persistance store
|
|
23
|
+
*/
|
|
24
|
+
private tokenType;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the provider user instance from the regular user details. Raises
|
|
27
|
+
* exception when id is missing
|
|
28
|
+
*/
|
|
29
|
+
private getUserForLogin;
|
|
30
|
+
/**
|
|
31
|
+
* Converts value to a sha256 hash
|
|
32
|
+
*/
|
|
33
|
+
private generateHash;
|
|
34
|
+
/**
|
|
35
|
+
* Converts expiry duration to an absolute date/time value
|
|
36
|
+
*/
|
|
37
|
+
private getExpiresAtDate;
|
|
38
|
+
/**
|
|
39
|
+
* Generates a new token + hash for the persistance
|
|
40
|
+
*/
|
|
41
|
+
private generateTokenForPersistance;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the request data to mark user as logged in
|
|
44
|
+
*/
|
|
45
|
+
login(user: any, options?: OATLoginOptions): Promise<ClientRequestData>;
|
|
46
|
+
/**
|
|
47
|
+
* Logout user
|
|
48
|
+
*/
|
|
49
|
+
logout(): Promise<void>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* @adonisjs/auth
|
|
4
|
+
*
|
|
5
|
+
* (c) AdonisJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.OATClient = void 0;
|
|
12
|
+
const luxon_1 = require("luxon");
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const utils_1 = require("@poppinss/utils");
|
|
15
|
+
const helpers_1 = require("@poppinss/utils/build/helpers");
|
|
16
|
+
const ProviderToken_1 = require("../../Tokens/ProviderToken");
|
|
17
|
+
/**
|
|
18
|
+
* OAT client to login a user during tests using the
|
|
19
|
+
* opaque tokens guard
|
|
20
|
+
*/
|
|
21
|
+
class OATClient {
|
|
22
|
+
constructor(name, config, provider, tokenProvider) {
|
|
23
|
+
this.name = name;
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.provider = provider;
|
|
26
|
+
this.tokenProvider = tokenProvider;
|
|
27
|
+
/**
|
|
28
|
+
* Length of the raw token. The hash length will vary
|
|
29
|
+
*/
|
|
30
|
+
this.tokenLength = 60;
|
|
31
|
+
/**
|
|
32
|
+
* Token type for the persistance store
|
|
33
|
+
*/
|
|
34
|
+
this.tokenType = this.config.tokenProvider.type || 'opaque_token';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the provider user instance from the regular user details. Raises
|
|
38
|
+
* exception when id is missing
|
|
39
|
+
*/
|
|
40
|
+
async getUserForLogin(user, identifierKey) {
|
|
41
|
+
const providerUser = await this.provider.getUserFor(user);
|
|
42
|
+
/**
|
|
43
|
+
* Ensure id exists on the user
|
|
44
|
+
*/
|
|
45
|
+
const id = providerUser.getId();
|
|
46
|
+
if (!id) {
|
|
47
|
+
throw new utils_1.Exception(`Cannot login user. Value of "${identifierKey}" is not defined`);
|
|
48
|
+
}
|
|
49
|
+
return providerUser;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Converts value to a sha256 hash
|
|
53
|
+
*/
|
|
54
|
+
generateHash(token) {
|
|
55
|
+
return (0, crypto_1.createHash)('sha256').update(token).digest('hex');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Converts expiry duration to an absolute date/time value
|
|
59
|
+
*/
|
|
60
|
+
getExpiresAtDate(expiresIn) {
|
|
61
|
+
if (!expiresIn) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const milliseconds = typeof expiresIn === 'string' ? helpers_1.string.toMs(expiresIn) : expiresIn;
|
|
65
|
+
return luxon_1.DateTime.local().plus({ milliseconds });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generates a new token + hash for the persistance
|
|
69
|
+
*/
|
|
70
|
+
generateTokenForPersistance(expiresIn) {
|
|
71
|
+
const token = helpers_1.string.generateRandom(this.tokenLength);
|
|
72
|
+
return {
|
|
73
|
+
token,
|
|
74
|
+
hash: this.generateHash(token),
|
|
75
|
+
expiresAt: this.getExpiresAtDate(expiresIn),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Returns the request data to mark user as logged in
|
|
80
|
+
*/
|
|
81
|
+
async login(user, options) {
|
|
82
|
+
/**
|
|
83
|
+
* Normalize options with defaults
|
|
84
|
+
*/
|
|
85
|
+
const { expiresIn, name, ...meta } = Object.assign({
|
|
86
|
+
name: 'Opaque Access Token',
|
|
87
|
+
}, options);
|
|
88
|
+
/**
|
|
89
|
+
* Since the login method is not exposed to the end user, we cannot expect
|
|
90
|
+
* them to instantiate and pass an instance of provider user, so we
|
|
91
|
+
* create one manually.
|
|
92
|
+
*/
|
|
93
|
+
const providerUser = await this.getUserForLogin(user, this.config.provider.identifierKey);
|
|
94
|
+
/**
|
|
95
|
+
* "getUserForLogin" raises exception when id is missing, so we can
|
|
96
|
+
* safely assume it is defined
|
|
97
|
+
*/
|
|
98
|
+
const id = providerUser.getId();
|
|
99
|
+
const token = this.generateTokenForPersistance(expiresIn);
|
|
100
|
+
/**
|
|
101
|
+
* Persist token to the database. Make sure that we are always
|
|
102
|
+
* passing the hash to the storage driver
|
|
103
|
+
*/
|
|
104
|
+
const providerToken = new ProviderToken_1.ProviderToken(name, token.hash, id, this.tokenType);
|
|
105
|
+
providerToken.expiresAt = token.expiresAt;
|
|
106
|
+
providerToken.meta = meta;
|
|
107
|
+
this.tokenId = await this.tokenProvider.write(providerToken);
|
|
108
|
+
return {
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: `Bearer ${helpers_1.base64.urlEncode(this.tokenId)}.${token.token}`,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Logout user
|
|
116
|
+
*/
|
|
117
|
+
async logout() {
|
|
118
|
+
if (this.tokenId) {
|
|
119
|
+
await this.tokenProvider.destroy(this.tokenId, this.tokenType);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.OATClient = OATClient;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SessionGuardConfig, GuardClientContract, UserProviderContract, ProviderUserContract } from '@ioc:Adonis/Addons/Auth';
|
|
2
|
+
/**
|
|
3
|
+
* Session client to login a user during tests using the
|
|
4
|
+
* sessions guard
|
|
5
|
+
*/
|
|
6
|
+
export declare class SessionClient implements GuardClientContract<any> {
|
|
7
|
+
name: string;
|
|
8
|
+
private config;
|
|
9
|
+
private provider;
|
|
10
|
+
constructor(name: string, config: SessionGuardConfig<any>, provider: UserProviderContract<any>);
|
|
11
|
+
/**
|
|
12
|
+
* The name of the session key name
|
|
13
|
+
*/
|
|
14
|
+
get sessionKeyName(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the provider user instance from the regular user details. Raises
|
|
17
|
+
* exception when id is missing
|
|
18
|
+
*/
|
|
19
|
+
protected getUserForLogin(user: any, identifierKey: string): Promise<ProviderUserContract<any>>;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the request data to mark user as logged in
|
|
22
|
+
*/
|
|
23
|
+
login(user: any): Promise<{
|
|
24
|
+
session: {
|
|
25
|
+
[x: string]: string | number;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* No need to logout when using session client.
|
|
30
|
+
* Session data is persisted within memory and will
|
|
31
|
+
* be cleared after each test
|
|
32
|
+
*/
|
|
33
|
+
logout(): Promise<void>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* @adonisjs/auth
|
|
4
|
+
*
|
|
5
|
+
* (c) AdonisJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.SessionClient = void 0;
|
|
12
|
+
const utils_1 = require("@poppinss/utils");
|
|
13
|
+
/**
|
|
14
|
+
* Session client to login a user during tests using the
|
|
15
|
+
* sessions guard
|
|
16
|
+
*/
|
|
17
|
+
class SessionClient {
|
|
18
|
+
constructor(name, config, provider) {
|
|
19
|
+
this.name = name;
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.provider = provider;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The name of the session key name
|
|
25
|
+
*/
|
|
26
|
+
get sessionKeyName() {
|
|
27
|
+
return `auth_${this.name}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the provider user instance from the regular user details. Raises
|
|
31
|
+
* exception when id is missing
|
|
32
|
+
*/
|
|
33
|
+
async getUserForLogin(user, identifierKey) {
|
|
34
|
+
const providerUser = await this.provider.getUserFor(user);
|
|
35
|
+
/**
|
|
36
|
+
* Ensure id exists on the user
|
|
37
|
+
*/
|
|
38
|
+
const id = providerUser.getId();
|
|
39
|
+
if (!id) {
|
|
40
|
+
throw new utils_1.Exception(`Cannot login user. Value of "${identifierKey}" is not defined`);
|
|
41
|
+
}
|
|
42
|
+
return providerUser;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns the request data to mark user as logged in
|
|
46
|
+
*/
|
|
47
|
+
async login(user) {
|
|
48
|
+
/**
|
|
49
|
+
* Since the login method is exposed to the end user, we cannot expect
|
|
50
|
+
* them to instantiate and return an instance of authenticatable, so
|
|
51
|
+
* we create one manually.
|
|
52
|
+
*/
|
|
53
|
+
const providerUser = await this.getUserForLogin(user, this.config.provider.identifierKey);
|
|
54
|
+
/**
|
|
55
|
+
* getUserForLogin raises exception when id is missing, so we can
|
|
56
|
+
* safely assume it is defined
|
|
57
|
+
*/
|
|
58
|
+
const id = providerUser.getId();
|
|
59
|
+
return {
|
|
60
|
+
session: {
|
|
61
|
+
[this.sessionKeyName]: id,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* No need to logout when using session client.
|
|
67
|
+
* Session data is persisted within memory and will
|
|
68
|
+
* be cleared after each test
|
|
69
|
+
*/
|
|
70
|
+
async logout() { }
|
|
71
|
+
}
|
|
72
|
+
exports.SessionClient = SessionClient;
|
|
@@ -113,8 +113,8 @@ class TokenDatabaseProvider {
|
|
|
113
113
|
created_at: luxon_1.DateTime.local().toFormat(client.dialect.dateTimeFormat),
|
|
114
114
|
...token.meta,
|
|
115
115
|
};
|
|
116
|
-
const [
|
|
117
|
-
return String(
|
|
116
|
+
const [row] = await client.table(this.config.table).insert(payload).returning('id');
|
|
117
|
+
return String(typeof row === 'number' ? row : row.id);
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* Removes a given token
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/auth",
|
|
3
|
-
"version": "8.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "8.2.0",
|
|
4
|
+
"description": "Official authentication provider for Adonis framework",
|
|
5
5
|
"types": "build/adonis-typings/index.d.ts",
|
|
6
6
|
"main": "build/providers/AuthProvider.js",
|
|
7
7
|
"files": [
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"mrm": "mrm --preset=@adonisjs/mrm-preset",
|
|
18
18
|
"pretest": "npm run lint",
|
|
19
|
-
"test": "node
|
|
20
|
-
"clean": "del build",
|
|
19
|
+
"test": "node -r @adonisjs/require-ts/build/register ./bin/test.ts",
|
|
20
|
+
"clean": "del-cli build",
|
|
21
21
|
"copyfiles": "copyfiles \"templates/**/*.txt\" build",
|
|
22
22
|
"compile": "npm run lint && npm run clean && tsc",
|
|
23
23
|
"build": "npm run compile && npm run copyfiles",
|
|
@@ -46,38 +46,41 @@
|
|
|
46
46
|
"url": "https://github.com/adonisjs/auth/issues"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@adonisjs/core": "^5.
|
|
50
|
-
"@adonisjs/i18n": "^1.5.
|
|
51
|
-
"@adonisjs/lucid": "^
|
|
52
|
-
"@adonisjs/mrm-preset": "^5.0.
|
|
53
|
-
"@adonisjs/redis": "^7.
|
|
54
|
-
"@adonisjs/repl": "^3.1.
|
|
55
|
-
"@adonisjs/require-ts": "^2.0.
|
|
56
|
-
"@adonisjs/session": "^6.
|
|
57
|
-
"@adonisjs/sink": "^5.
|
|
58
|
-
"@
|
|
59
|
-
"@
|
|
60
|
-
"@
|
|
61
|
-
"@
|
|
49
|
+
"@adonisjs/core": "^5.8.2",
|
|
50
|
+
"@adonisjs/i18n": "^1.5.5",
|
|
51
|
+
"@adonisjs/lucid": "^18.0.0",
|
|
52
|
+
"@adonisjs/mrm-preset": "^5.0.3",
|
|
53
|
+
"@adonisjs/redis": "^7.3.0",
|
|
54
|
+
"@adonisjs/repl": "^3.1.10",
|
|
55
|
+
"@adonisjs/require-ts": "^2.0.11",
|
|
56
|
+
"@adonisjs/session": "^6.4.0",
|
|
57
|
+
"@adonisjs/sink": "^5.3.1",
|
|
58
|
+
"@japa/assert": "^1.3.4",
|
|
59
|
+
"@japa/preset-adonis": "^1.0.16",
|
|
60
|
+
"@japa/run-failed-tests": "^1.0.6",
|
|
61
|
+
"@japa/runner": "^2.0.8",
|
|
62
|
+
"@japa/spec-reporter": "^1.1.11",
|
|
63
|
+
"@poppinss/dev-utils": "^2.0.3",
|
|
64
|
+
"@types/node": "^17.0.35",
|
|
65
|
+
"@types/supertest": "^2.0.12",
|
|
62
66
|
"copyfiles": "^2.4.1",
|
|
63
67
|
"del-cli": "^4.0.1",
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"eslint-config-prettier": "^8.
|
|
68
|
+
"eslint": "^8.16.0",
|
|
69
|
+
"eslint-config-prettier": "^8.5.0",
|
|
66
70
|
"eslint-plugin-adonis": "^2.1.0",
|
|
67
71
|
"eslint-plugin-prettier": "^4.0.0",
|
|
68
|
-
"github-label-sync": "^2.0
|
|
69
|
-
"husky": "^
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"np": "^7.6.0",
|
|
72
|
+
"github-label-sync": "^2.2.0",
|
|
73
|
+
"husky": "^8.0.1",
|
|
74
|
+
"mrm": "^4.0.0",
|
|
75
|
+
"np": "^7.6.1",
|
|
73
76
|
"phc-bcrypt": "^1.0.7",
|
|
74
|
-
"pino-pretty": "^7.
|
|
75
|
-
"prettier": "^2.
|
|
77
|
+
"pino-pretty": "^7.6.1",
|
|
78
|
+
"prettier": "^2.6.2",
|
|
76
79
|
"reflect-metadata": "^0.1.13",
|
|
77
80
|
"set-cookie-parser": "^2.4.8",
|
|
78
|
-
"supertest": "^6.2.
|
|
81
|
+
"supertest": "^6.2.3",
|
|
79
82
|
"ts-essentials": "^9.1.2",
|
|
80
|
-
"typescript": "^4.6.
|
|
83
|
+
"typescript": "^4.6.4"
|
|
81
84
|
},
|
|
82
85
|
"nyc": {
|
|
83
86
|
"exclude": [
|
|
@@ -97,16 +100,17 @@
|
|
|
97
100
|
"anyBranch": false
|
|
98
101
|
},
|
|
99
102
|
"dependencies": {
|
|
100
|
-
"@poppinss/hooks": "^5.0.
|
|
101
|
-
"@poppinss/utils": "^4.0.
|
|
102
|
-
"luxon": "^2.
|
|
103
|
+
"@poppinss/hooks": "^5.0.3",
|
|
104
|
+
"@poppinss/utils": "^4.0.4",
|
|
105
|
+
"luxon": "^2.4.0",
|
|
106
|
+
"sqlite3": "^5.0.8"
|
|
103
107
|
},
|
|
104
108
|
"peerDependencies": {
|
|
105
|
-
"@adonisjs/core": "^5.
|
|
106
|
-
"@adonisjs/i18n": "^1.
|
|
107
|
-
"@adonisjs/lucid": "^17.
|
|
108
|
-
"@adonisjs/redis": "^7.
|
|
109
|
-
"@adonisjs/session": "^6.
|
|
109
|
+
"@adonisjs/core": "^5.7.1",
|
|
110
|
+
"@adonisjs/i18n": "^1.5.0",
|
|
111
|
+
"@adonisjs/lucid": "^17.2.0",
|
|
112
|
+
"@adonisjs/redis": "^7.2.0",
|
|
113
|
+
"@adonisjs/session": "^6.2.0"
|
|
110
114
|
},
|
|
111
115
|
"peerDependenciesMeta": {
|
|
112
116
|
"@adonisjs/i18n": {
|