1
+ import type { Document } from 'bson' ;
2
+
1
3
import { MongoInvalidArgumentError , MongoMissingCredentialsError } from '../../error' ;
2
4
import 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' ;
4
7
import type { MongoCredentials } from './mongo_credentials' ;
5
8
import { AwsServiceWorkflow } from './mongodb_oidc/aws_service_workflow' ;
6
9
import { 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.' ;
8
13
9
14
/**
10
15
* @public
11
16
* @experimental
12
17
*/
13
- export interface OIDCMechanismServerStep1 {
14
- authorizationEndpoint ?: string ;
15
- tokenEndpoint ?: string ;
16
- deviceAuthorizationEndpoint ?: string ;
18
+ export interface IdPServerInfo {
19
+ issuer : string ;
17
20
clientId : string ;
18
- clientSecret ?: string ;
19
21
requestScopes ?: string [ ] ;
20
22
}
21
23
22
24
/**
23
25
* @public
24
26
* @experimental
25
27
*/
26
- export interface OIDCRequestTokenResult {
28
+ export interface IdPServerResponse {
27
29
accessToken : string ;
28
30
expiresInSeconds ?: number ;
29
31
refreshToken ?: string ;
30
32
}
31
33
34
+ /**
35
+ * @public
36
+ * @experimental
37
+ */
38
+ export interface OIDCCallbackContext {
39
+ refreshToken ?: string ;
40
+ timeoutSeconds ?: number ;
41
+ timeoutContext ?: AbortSignal ;
42
+ version : number ;
43
+ }
44
+
32
45
/**
33
46
* @public
34
47
* @experimental
35
48
*/
36
49
export type OIDCRequestFunction = (
37
- principalName : string ,
38
- serverResult : OIDCMechanismServerStep1 ,
39
- timeout : AbortSignal | number
40
- ) => Promise < OIDCRequestTokenResult > ;
50
+ info : IdPServerInfo ,
51
+ context : OIDCCallbackContext
52
+ ) => Promise < IdPServerResponse > ;
41
53
42
54
/**
43
55
* @public
44
56
* @experimental
45
57
*/
46
58
export 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 > ;
52
62
53
63
type ProviderName = 'aws' | 'callback' ;
54
64
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
+
55
83
/** @internal */
56
84
export const OIDC_WORKFLOWS : Map < ProviderName , Workflow > = new Map ( ) ;
57
85
OIDC_WORKFLOWS . set ( 'callback' , new CallbackWorkflow ( ) ) ;
@@ -73,19 +101,10 @@ export class MongoDBOIDC extends AuthProvider {
73
101
* Authenticate using OIDC
74
102
*/
75
103
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 ) ;
86
106
const workflow = getWorkflow ( credentials ) ;
87
-
88
- await workflow . execute ( connection , credentials , reauthenticating ) ;
107
+ await workflow . execute ( connection , credentials , reauthenticating , response ) ;
89
108
}
90
109
91
110
/**
@@ -95,19 +114,24 @@ export class MongoDBOIDC extends AuthProvider {
95
114
handshakeDoc : HandshakeDocument ,
96
115
authContext : AuthContext
97
116
) : 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 ) ;
104
118
const workflow = getWorkflow ( credentials ) ;
105
-
106
- const result = await workflow . speculativeAuth ( ) ;
119
+ const result = await workflow . speculativeAuth ( credentials ) ;
107
120
return { ...handshakeDoc , ...result } ;
108
121
}
109
122
}
110
123
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
+
111
135
/**
112
136
* Gets either a device workflow or callback workflow.
113
137
*/
0 commit comments