@@ -3,21 +3,21 @@ import { BSON, type Document } from 'bson';
33import { MongoMissingCredentialsError } from '../../../error' ;
44import { ns } from '../../../utils' ;
55import type { Connection } from '../../connection' ;
6- import type { MongoCredentials } from '../mongo_credentials' ;
6+ import type { AuthMechanismProperties , MongoCredentials } from '../mongo_credentials' ;
77import type {
8- IdPServerInfo ,
8+ IdPInfo ,
99 IdPServerResponse ,
10- OIDCRequestFunction ,
11- OIDCTokenParams ,
10+ OIDCCallbackFunction ,
11+ OIDCCallbackParams ,
1212 Workflow
1313} from '../mongodb_oidc' ;
1414import { finishCommandDocument , startCommandDocument } from './command_builders' ;
1515
1616/** The current version of OIDC implementation. */
1717const OIDC_VERSION = 1 ;
1818
19- /** 5 minutes in seconds */
20- const TIMEOUT_S = 300 ;
19+ /** 5 minutes in milliseconds */
20+ const HUMAN_TIMEOUT_MS = 300000 ;
2121
2222/** Properties allowed on results of callbacks. */
2323const RESULT_PROPERTIES = [ 'accessToken' , 'expiresInSeconds' , 'refreshToken' ] ;
@@ -26,7 +26,15 @@ const RESULT_PROPERTIES = ['accessToken', 'expiresInSeconds', 'refreshToken'];
2626const CALLBACK_RESULT_ERROR =
2727 'User provided OIDC callbacks must return a valid object with an accessToken.' ;
2828
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+ }
3038
3139/**
3240 * OIDC implementation of a callback based workflow.
@@ -67,19 +75,11 @@ export class CallbackWorkflow implements Workflow {
6775 credentials : MongoCredentials ,
6876 response ?: Document
6977 ) : 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 ) ;
7479 const startDocument = await this . startAuthentication ( connection , credentials , response ) ;
7580 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 ) ;
8383 const result = await this . finishAuthentication (
8484 connection ,
8585 credentials ,
@@ -136,15 +136,18 @@ export class CallbackWorkflow implements Workflow {
136136 private async fetchAccessToken (
137137 connection : Connection ,
138138 credentials : MongoCredentials ,
139- serverInfo : IdPServerInfo ,
140- requestCallback : OIDCRequestFunction
139+ idpInfo : IdPInfo ,
140+ callbackInfo : OIDCCallbackInfo
141141 ) : 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?
145148 } ;
146149 // With no token in the cache we use the request callback.
147- const result = await requestCallback ( params ) ;
150+ const result = await callbackInfo . callback ( params ) ;
148151 // Validate that the result returned by the callback is acceptable. If it is not
149152 // we must clear the token result from the cache.
150153 if ( isCallbackResultInvalid ( result ) ) {
@@ -154,6 +157,20 @@ export class CallbackWorkflow implements Workflow {
154157 }
155158}
156159
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+
157174/**
158175 * Determines if a result returned from a request or refresh callback
159176 * function is invalid. This means the result is nullish, doesn't contain
0 commit comments