1+ import type { Document } from 'bson' ;
2+
13import { MongoInvalidArgumentError , MongoMissingCredentialsError } from '../../error' ;
24import type { HandshakeDocument } from '../connect' ;
3- import { type AuthContext , AuthProvider } from './auth_provider' ;
5+ import type { Connection } from '../connection' ;
6+ import { AuthContext , AuthProvider } from './auth_provider' ;
47import type { MongoCredentials } from './mongo_credentials' ;
58import { AwsServiceWorkflow } from './mongodb_oidc/aws_service_workflow' ;
69import { CallbackWorkflow } from './mongodb_oidc/callback_workflow' ;
7- import type { Workflow } from './mongodb_oidc/workflow' ;
10+
11+ /** Error when credentials are missing. */
12+ const MISSING_CREDENTIALS_ERROR = 'AuthContext must provide credentials.' ;
813
914/**
1015 * @public
1116 * @experimental
1217 */
13- export interface OIDCMechanismServerStep1 {
14- authorizationEndpoint ?: string ;
15- tokenEndpoint ?: string ;
16- deviceAuthorizationEndpoint ?: string ;
18+ export interface IdPServerInfo {
19+ issuer : string ;
1720 clientId : string ;
18- clientSecret ?: string ;
1921 requestScopes ?: string [ ] ;
2022}
2123
2224/**
2325 * @public
2426 * @experimental
2527 */
26- export interface OIDCRequestTokenResult {
28+ export interface IdPServerResponse {
2729 accessToken : string ;
2830 expiresInSeconds ?: number ;
2931 refreshToken ?: string ;
3032}
3133
34+ /**
35+ * @public
36+ * @experimental
37+ */
38+ export interface OIDCCallbackContext {
39+ refreshToken ?: string ;
40+ timeoutSeconds ?: number ;
41+ timeoutContext ?: AbortSignal ;
42+ version : number ;
43+ }
44+
3245/**
3346 * @public
3447 * @experimental
3548 */
3649export type OIDCRequestFunction = (
37- principalName : string ,
38- serverResult : OIDCMechanismServerStep1 ,
39- timeout : AbortSignal | number
40- ) => Promise < OIDCRequestTokenResult > ;
50+ info : IdPServerInfo ,
51+ context : OIDCCallbackContext
52+ ) => Promise < IdPServerResponse > ;
4153
4254/**
4355 * @public
4456 * @experimental
4557 */
4658export type OIDCRefreshFunction = (
47- principalName : string ,
48- serverResult : OIDCMechanismServerStep1 ,
49- result : OIDCRequestTokenResult ,
50- timeout : AbortSignal | number
51- ) => Promise < OIDCRequestTokenResult > ;
59+ info : IdPServerInfo ,
60+ context : OIDCCallbackContext
61+ ) => Promise < IdPServerResponse > ;
5262
5363type ProviderName = 'aws' | 'callback' ;
5464
65+ export interface Workflow {
66+ /**
67+ * All device workflows must implement this method in order to get the access
68+ * token and then call authenticate with it.
69+ */
70+ execute (
71+ connection : Connection ,
72+ credentials : MongoCredentials ,
73+ reauthenticating : boolean ,
74+ response ?: Document
75+ ) : Promise < Document > ;
76+
77+ /**
78+ * Get the document to add for speculative authentication.
79+ */
80+ speculativeAuth ( credentials : MongoCredentials ) : Promise < Document > ;
81+ }
82+
5583/** @internal */
5684export const OIDC_WORKFLOWS : Map < ProviderName , Workflow > = new Map ( ) ;
5785OIDC_WORKFLOWS . set ( 'callback' , new CallbackWorkflow ( ) ) ;
@@ -73,19 +101,10 @@ export class MongoDBOIDC extends AuthProvider {
73101 * Authenticate using OIDC
74102 */
75103 override async auth ( authContext : AuthContext ) : Promise < void > {
76- const { connection, credentials, response, reauthenticating } = authContext ;
77-
78- if ( response ?. speculativeAuthenticate ) {
79- return ;
80- }
81-
82- if ( ! credentials ) {
83- throw new MongoMissingCredentialsError ( 'AuthContext must provide credentials.' ) ;
84- }
85-
104+ const { connection, reauthenticating, response } = authContext ;
105+ const credentials = getCredentials ( authContext ) ;
86106 const workflow = getWorkflow ( credentials ) ;
87-
88- await workflow . execute ( connection , credentials , reauthenticating ) ;
107+ await workflow . execute ( connection , credentials , reauthenticating , response ) ;
89108 }
90109
91110 /**
@@ -95,19 +114,24 @@ export class MongoDBOIDC extends AuthProvider {
95114 handshakeDoc : HandshakeDocument ,
96115 authContext : AuthContext
97116 ) : Promise < HandshakeDocument > {
98- const { credentials } = authContext ;
99-
100- if ( ! credentials ) {
101- throw new MongoMissingCredentialsError ( 'AuthContext must provide credentials.' ) ;
102- }
103-
117+ const credentials = getCredentials ( authContext ) ;
104118 const workflow = getWorkflow ( credentials ) ;
105-
106- const result = await workflow . speculativeAuth ( ) ;
119+ const result = await workflow . speculativeAuth ( credentials ) ;
107120 return { ...handshakeDoc , ...result } ;
108121 }
109122}
110123
124+ /**
125+ * Get credentials from the auth context, throwing if they do not exist.
126+ */
127+ function getCredentials ( authContext : AuthContext ) : MongoCredentials {
128+ const { credentials } = authContext ;
129+ if ( ! credentials ) {
130+ throw new MongoMissingCredentialsError ( MISSING_CREDENTIALS_ERROR ) ;
131+ }
132+ return credentials ;
133+ }
134+
111135/**
112136 * Gets either a device workflow or callback workflow.
113137 */
0 commit comments