@@ -3,21 +3,21 @@ import { BSON, type Document } from 'bson';
3
3
import { MongoMissingCredentialsError } from '../../../error' ;
4
4
import { ns } from '../../../utils' ;
5
5
import type { Connection } from '../../connection' ;
6
- import type { MongoCredentials } from '../mongo_credentials' ;
6
+ import type { AuthMechanismProperties , MongoCredentials } from '../mongo_credentials' ;
7
7
import type {
8
- IdPServerInfo ,
8
+ IdPInfo ,
9
9
IdPServerResponse ,
10
- OIDCRequestFunction ,
11
- OIDCTokenParams ,
10
+ OIDCCallbackFunction ,
11
+ OIDCCallbackParams ,
12
12
Workflow
13
13
} from '../mongodb_oidc' ;
14
14
import { finishCommandDocument , startCommandDocument } from './command_builders' ;
15
15
16
16
/** The current version of OIDC implementation. */
17
17
const OIDC_VERSION = 1 ;
18
18
19
- /** 5 minutes in seconds */
20
- const TIMEOUT_S = 300 ;
19
+ /** 5 minutes in milliseconds */
20
+ const HUMAN_TIMEOUT_MS = 300000 ;
21
21
22
22
/** Properties allowed on results of callbacks. */
23
23
const RESULT_PROPERTIES = [ 'accessToken' , 'expiresInSeconds' , 'refreshToken' ] ;
@@ -26,7 +26,15 @@ const RESULT_PROPERTIES = ['accessToken', 'expiresInSeconds', 'refreshToken'];
26
26
const CALLBACK_RESULT_ERROR =
27
27
'User provided OIDC callbacks must return a valid object with an accessToken.' ;
28
28
29
- const NO_REQUEST_CALLBACK = 'No OIDC_TOKEN_CALLBACK provided for callback workflow.' ;
29
+ const NO_CALLBACK = 'No OIDC_CALLBACK or OIDC_HUMAN_CALLBACK provided for callback workflow.' ;
30
+
31
+ /**
32
+ * The OIDC callback information.
33
+ */
34
+ interface OIDCCallbackInfo {
35
+ callback : OIDCCallbackFunction ;
36
+ isHumanWorkflow : boolean ;
37
+ }
30
38
31
39
/**
32
40
* OIDC implementation of a callback based workflow.
@@ -67,19 +75,11 @@ export class CallbackWorkflow implements Workflow {
67
75
credentials : MongoCredentials ,
68
76
response ?: Document
69
77
) : Promise < Document > {
70
- const requestCallback = credentials . mechanismProperties . OIDC_TOKEN_CALLBACK ;
71
- if ( ! requestCallback ) {
72
- throw new MongoMissingCredentialsError ( NO_REQUEST_CALLBACK ) ;
73
- }
78
+ const callbackInfo = getCallback ( credentials . mechanismProperties ) ;
74
79
const startDocument = await this . startAuthentication ( connection , credentials , response ) ;
75
80
const conversationId = startDocument . conversationId ;
76
- const serverResult = BSON . deserialize ( startDocument . payload . buffer ) as IdPServerInfo ;
77
- const tokenResult = await this . fetchAccessToken (
78
- connection ,
79
- credentials ,
80
- serverResult ,
81
- requestCallback
82
- ) ;
81
+ const idpInfo = BSON . deserialize ( startDocument . payload . buffer ) as IdPInfo ;
82
+ const tokenResult = await this . fetchAccessToken ( connection , credentials , idpInfo , callbackInfo ) ;
83
83
const result = await this . finishAuthentication (
84
84
connection ,
85
85
credentials ,
@@ -136,15 +136,18 @@ export class CallbackWorkflow implements Workflow {
136
136
private async fetchAccessToken (
137
137
connection : Connection ,
138
138
credentials : MongoCredentials ,
139
- serverInfo : IdPServerInfo ,
140
- requestCallback : OIDCRequestFunction
139
+ idpInfo : IdPInfo ,
140
+ callbackInfo : OIDCCallbackInfo
141
141
) : Promise < IdPServerResponse > {
142
- const params : OIDCTokenParams = {
143
- timeoutContext : AbortSignal . timeout ( TIMEOUT_S ) ,
144
- version : OIDC_VERSION
142
+ const params : OIDCCallbackParams = {
143
+ timeoutContext : AbortSignal . timeout (
144
+ callbackInfo . isHumanWorkflow ? HUMAN_TIMEOUT_MS : HUMAN_TIMEOUT_MS
145
+ ) , // TODO: CSOT
146
+ version : OIDC_VERSION ,
147
+ idpInfo : idpInfo // TODO: refreshToken?
145
148
} ;
146
149
// With no token in the cache we use the request callback.
147
- const result = await requestCallback ( params ) ;
150
+ const result = await callbackInfo . callback ( params ) ;
148
151
// Validate that the result returned by the callback is acceptable. If it is not
149
152
// we must clear the token result from the cache.
150
153
if ( isCallbackResultInvalid ( result ) ) {
@@ -154,6 +157,20 @@ export class CallbackWorkflow implements Workflow {
154
157
}
155
158
}
156
159
160
+ /**
161
+ * Returns a callback, either machine or human, and a flag whether the workflow is
162
+ * human or not.
163
+ */
164
+ function getCallback ( mechanismProperties : AuthMechanismProperties ) : OIDCCallbackInfo {
165
+ if ( ! mechanismProperties . OIDC_CALLBACK || ! mechanismProperties . OIDC_HUMAN_CALLBACK ) {
166
+ throw new MongoMissingCredentialsError ( NO_CALLBACK ) ;
167
+ }
168
+ if ( mechanismProperties . OIDC_CALLBACK ) {
169
+ return { callback : mechanismProperties . OIDC_CALLBACK , isHumanWorkflow : false } ;
170
+ }
171
+ return { callback : mechanismProperties . OIDC_HUMAN_CALLBACK , isHumanWorkflow : true } ;
172
+ }
173
+
157
174
/**
158
175
* Determines if a result returned from a request or refresh callback
159
176
* function is invalid. This means the result is nullish, doesn't contain
0 commit comments