1
- const OAuth2Server = require ( '../../../' ) ;
2
- const db = require ( './db' ) ;
3
- const model = require ( './model' ) ;
4
- const Request = require ( '../../../lib/request' ) ;
5
- const Response = require ( '../../../lib/response' ) ;
1
+ /**
2
+ * Request
3
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.2
4
+ *
5
+ * grant_type
6
+ * REQUIRED. Value MUST be set to "password".
7
+ * username
8
+ * REQUIRED. The resource owner username.
9
+ * password
10
+ * REQUIRED. The resource owner password.
11
+ * scope
12
+ * OPTIONAL. The scope of the access request as described by Section 3.3.
13
+ */
14
+
15
+ /**
16
+ * Response
17
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.1
18
+ *
19
+ * access_token
20
+ * REQUIRED. The access token issued by the authorization server.
21
+ * token_type
22
+ * REQUIRED. The type of the token issued as described in
23
+ * Section 7.1. Value is case insensitive.
24
+ * expires_in
25
+ * RECOMMENDED. The lifetime in seconds of the access token. For
26
+ * example, the value "3600" denotes that the access token will
27
+ * expire in one hour from the time the response was generated.
28
+ * If omitted, the authorization server SHOULD provide the
29
+ * expiration time via other means or document the default value.
30
+ * refresh_token
31
+ * OPTIONAL. The refresh token, which can be used to obtain new
32
+ * access tokens using the same authorization grant as described
33
+ * in Section 6.
34
+ * scope
35
+ * OPTIONAL, if identical to the scope requested by the client;
36
+ * otherwise, REQUIRED. The scope of the access token as
37
+ * described by Section 3.3.
38
+ */
39
+
40
+ /**
41
+ * Response (error)
42
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
43
+ *
44
+ * error
45
+ * REQUIRED. A single ASCII [USASCII] error code from the following:
46
+ * invalid_request, invalid_client, invalid_grant
47
+ * unauthorized_client, unsupported_grant_type, invalid_scope
48
+ * error_description
49
+ * OPTIONAL. Human-readable ASCII [USASCII] text providing
50
+ * additional information, used to assist the client developer in
51
+ * understanding the error that occurred.
52
+ * error_uri
53
+ * OPTIONAL. A URI identifying a human-readable web page with
54
+ * information about the error, used to provide the client
55
+ * developer with additional information about the error.
56
+ */
57
+
58
+ const OAuth2Server = require ( '../..' ) ;
59
+ const DB = require ( '../helpers/db' ) ;
60
+ const createModel = require ( '../helpers/model' ) ;
61
+ const createRequest = require ( '../helpers/request' ) ;
62
+ const Response = require ( '../../lib/response' ) ;
6
63
7
64
require ( 'chai' ) . should ( ) ;
8
65
66
+ const db = new DB ( ) ;
67
+
9
68
const auth = new OAuth2Server ( {
10
- model : model
69
+ model : createModel ( db )
11
70
} ) ;
12
71
13
72
const user = db . saveUser ( { id : 1 , username : 'test' , password : 'test' } ) ;
14
73
const client = db . saveClient ( { id : 'a' , secret : 'b' , grants : [ 'password' ] } ) ;
15
74
const scope = 'read write' ;
16
75
17
76
function createDefaultRequest ( ) {
18
- const request = new Request ( {
77
+ return createRequest ( {
19
78
body : {
20
79
grant_type : 'password' ,
21
80
client_id : client . id ,
@@ -28,20 +87,12 @@ function createDefaultRequest () {
28
87
'content-type' : 'application/x-www-form-urlencoded'
29
88
} ,
30
89
method : 'POST' ,
31
- query : { }
32
90
} ) ;
33
-
34
- request . is = function ( header ) {
35
- return this . headers [ 'content-type' ] === header ;
36
- } ;
37
-
38
- return request ;
39
91
}
40
92
41
- describe ( 'PasswordGrantType Integration Flow ' , function ( ) {
93
+ describe ( 'PasswordGrantType Compliance ' , function ( ) {
42
94
describe ( 'Authenticate' , function ( ) {
43
-
44
- it ( 'Succesfull authentication' , async function ( ) {
95
+ it ( 'Succesfull authorization' , async function ( ) {
45
96
const request = createDefaultRequest ( ) ;
46
97
const response = new Response ( { } ) ;
47
98
@@ -62,6 +113,32 @@ describe('PasswordGrantType Integration Flow', function () {
62
113
db . refreshTokens . has ( token . refreshToken ) . should . equal ( true ) ;
63
114
} ) ;
64
115
116
+ it ( 'Succesfull authorization and authentication' , async function ( ) {
117
+ const tokenRequest = createDefaultRequest ( ) ;
118
+ const tokenResponse = new Response ( { } ) ;
119
+
120
+ const token = await auth . token ( tokenRequest , tokenResponse , { } ) ;
121
+
122
+ const authenticationRequest = createRequest ( {
123
+ body : { } ,
124
+ headers : {
125
+ 'Authorization' : `Bearer ${ token . accessToken } `
126
+ } ,
127
+ method : 'GET' ,
128
+ query : { }
129
+ } ) ;
130
+ const authenticationResponse = new Response ( { } ) ;
131
+
132
+ const authenticated = await auth . authenticate (
133
+ authenticationRequest ,
134
+ authenticationResponse ,
135
+ { } ) ;
136
+
137
+ authenticated . scope . should . equal ( scope ) ;
138
+ authenticated . user . should . be . an ( 'object' ) ;
139
+ authenticated . client . should . be . an ( 'object' ) ;
140
+ } ) ;
141
+
65
142
it ( 'Username missing' , async function ( ) {
66
143
const request = createDefaultRequest ( ) ;
67
144
const response = new Response ( { } ) ;
0 commit comments