@@ -77,6 +77,19 @@ async function delay(ms: number) {
77
77
return await new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
78
78
}
79
79
80
+ function testAuthCodeFlow (
81
+ fn : ( opts : Partial < MongoDBOIDCPluginOptions > ) => Mocha . Func
82
+ ) : void {
83
+ for ( const skipNonceInAuthCodeRequest of [ true , false ] ) {
84
+ describe ( `with skipNonceInAuthCodeRequest: ${ skipNonceInAuthCodeRequest . toString ( ) } ` , function ( ) {
85
+ it (
86
+ 'can successfully authenticate with auth code flow' ,
87
+ fn ( { skipNonceInAuthCodeRequest } )
88
+ ) ;
89
+ } ) ;
90
+ }
91
+ }
92
+
80
93
describe ( 'OIDC plugin (local OIDC provider)' , function ( ) {
81
94
this . timeout ( 90_000 ) ;
82
95
@@ -138,18 +151,42 @@ describe('OIDC plugin (local OIDC provider)', function () {
138
151
plugin = createMongoDBOIDCPlugin ( pluginOptions ) ;
139
152
} ) ;
140
153
141
- it ( 'can request tokens through the browser' , async function ( ) {
142
- const result = await requestToken (
143
- plugin ,
144
- provider . getMongodbOIDCDBInfo ( )
145
- ) ;
146
- const accessTokenContents = getJWTContents ( result . accessToken ) ;
147
- expect ( accessTokenContents . sub ) . to . equal ( 'testuser' ) ;
148
- expect ( accessTokenContents . client_id ) . to . equal (
149
- provider . getMongodbOIDCDBInfo ( ) . clientId
150
- ) ;
151
- verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
152
- } ) ;
154
+ testAuthCodeFlow (
155
+ ( opts ) =>
156
+ async function ( ) {
157
+ pluginOptions = {
158
+ ...pluginOptions ,
159
+ ...opts ,
160
+ } ;
161
+ plugin = createMongoDBOIDCPlugin ( pluginOptions ) ;
162
+ let idToken : string | undefined ;
163
+ plugin . logger . once ( 'mongodb-oidc-plugin:auth-succeeded' , ( event ) => {
164
+ idToken = event . tokens . idToken ;
165
+ } ) ;
166
+
167
+ const result = await requestToken (
168
+ plugin ,
169
+ provider . getMongodbOIDCDBInfo ( )
170
+ ) ;
171
+ const accessTokenContents = getJWTContents ( result . accessToken ) ;
172
+ expect ( accessTokenContents . sub ) . to . equal ( 'testuser' ) ;
173
+ expect ( accessTokenContents . client_id ) . to . equal (
174
+ provider . getMongodbOIDCDBInfo ( ) . clientId
175
+ ) ;
176
+
177
+ verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
178
+
179
+ expect ( idToken ) . to . not . be . undefined ;
180
+
181
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know it's non-null from the above check
182
+ const idTokenContents = getJWTContents ( idToken ! ) ;
183
+ if ( opts . skipNonceInAuthCodeRequest ) {
184
+ expect ( idTokenContents . nonce ) . to . be . undefined ;
185
+ } else {
186
+ expect ( idTokenContents . nonce ) . to . not . be . undefined ;
187
+ }
188
+ }
189
+ ) ;
153
190
154
191
it ( 'will re-use tokens while they are valid if no username was provided' , async function ( ) {
155
192
const skipAuthAttemptEvent = once (
@@ -1017,18 +1054,22 @@ describe('OIDC plugin (local OIDC provider)', function () {
1017
1054
} ;
1018
1055
} ) ;
1019
1056
1020
- it ( 'can successfully authenticate with Okta using auth code flow' , async function ( ) {
1021
- plugin = createMongoDBOIDCPlugin ( {
1022
- ...defaultOpts ,
1023
- allowedFlows : [ 'auth-code' ] ,
1024
- openBrowser : ( opts ) =>
1025
- oktaBrowserAuthCodeFlow ( { ...opts , username, password } ) ,
1026
- } ) ;
1027
- const result = await requestToken ( plugin , metadata ) ;
1057
+ testAuthCodeFlow (
1058
+ ( opts ) =>
1059
+ async function ( ) {
1060
+ plugin = createMongoDBOIDCPlugin ( {
1061
+ ...defaultOpts ,
1062
+ allowedFlows : [ 'auth-code' ] ,
1063
+ openBrowser : ( opts ) =>
1064
+ oktaBrowserAuthCodeFlow ( { ...opts , username, password } ) ,
1065
+ ...opts ,
1066
+ } ) ;
1067
+ const result = await requestToken ( plugin , metadata ) ;
1028
1068
1029
- validateToken ( getJWTContents ( result . accessToken ) ) ;
1030
- verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
1031
- } ) ;
1069
+ validateToken ( getJWTContents ( result . accessToken ) ) ;
1070
+ verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
1071
+ }
1072
+ ) ;
1032
1073
1033
1074
it ( 'can successfully authenticate with Okta using device auth flow' , async function ( ) {
1034
1075
plugin = createMongoDBOIDCPlugin ( {
@@ -1087,18 +1128,22 @@ describe('OIDC plugin (local OIDC provider)', function () {
1087
1128
} ;
1088
1129
} ) ;
1089
1130
1090
- it ( 'can successfully authenticate with Azure using auth code flow' , async function ( ) {
1091
- plugin = createMongoDBOIDCPlugin ( {
1092
- ...defaultOpts ,
1093
- allowedFlows : [ 'auth-code' ] ,
1094
- openBrowser : ( opts ) =>
1095
- azureBrowserAuthCodeFlow ( { ...opts , username, password } ) ,
1096
- } ) ;
1097
- const result = await requestToken ( plugin , metadata ) ;
1131
+ testAuthCodeFlow (
1132
+ ( opts ) =>
1133
+ async function ( ) {
1134
+ plugin = createMongoDBOIDCPlugin ( {
1135
+ ...defaultOpts ,
1136
+ allowedFlows : [ 'auth-code' ] ,
1137
+ openBrowser : ( opts ) =>
1138
+ azureBrowserAuthCodeFlow ( { ...opts , username, password } ) ,
1139
+ ...opts ,
1140
+ } ) ;
1141
+ const result = await requestToken ( plugin , metadata ) ;
1098
1142
1099
- validateToken ( getJWTContents ( result . accessToken ) ) ;
1100
- verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
1101
- } ) ;
1143
+ validateToken ( getJWTContents ( result . accessToken ) ) ;
1144
+ verifySuccessfulAuthCodeFlowLog ( await readLog ( ) ) ;
1145
+ }
1146
+ ) ;
1102
1147
1103
1148
it ( 'can successfully authenticate with Azure using device auth flow' , async function ( ) {
1104
1149
plugin = createMongoDBOIDCPlugin ( {
0 commit comments