@@ -7,10 +7,7 @@ import { credentialOperations } from '@/lib/credentials/application/operations'
77import { storedAwsAuthType } from '@/lib/credentials/aws-service-account.server'
88import { storedDatabricksAuthType } from '@/lib/credentials/databricks-service-account.server'
99import { isGoogleWorkloadIdentitySecret } from '@/lib/credentials/google-workload-identity'
10- import {
11- storedMicrosoftAppAuthType ,
12- storedMicrosoftAppCloud ,
13- } from '@/lib/credentials/microsoft-app-service-account.server'
10+ import { storedMicrosoftAppReconnectFields } from '@/lib/credentials/microsoft-app-service-account.server'
1411import type { MicrosoftCloudId } from '@/lib/credentials/microsoft-clouds'
1512import { storedSnowflakeAuthType } from '@/lib/credentials/snowflake-service-account.server'
1613import {
@@ -55,22 +52,38 @@ export type PrepareWorkloadIdentityResult =
5552 expiresAt : string
5653 } & ReconnectAuthTypeField )
5754
55+ /** What a reconnect reopens on, read from a credential's stored secret. */
56+ interface StoredReconnectFields < P extends WorkloadIdentityProvider > {
57+ authType ?: WorkloadIdentityProviderAuthType < P >
58+ /** A Microsoft app credential's national cloud; absent for a global one and other providers. */
59+ cloud ?: MicrosoftCloudId
60+ }
61+
62+ function authTypeOnly < A extends string > (
63+ readAuthType : ( decrypted : string ) => A | undefined
64+ ) : ( decrypted : string ) => { authType ?: A } {
65+ return ( decrypted ) => {
66+ const authType = readAuthType ( decrypted )
67+ return authType ? { authType } : { }
68+ }
69+ }
70+
5871/**
5972 * Every keyless provider also has key-based modes under the same provider ID, so a
60- * reconnect reads the stored secret's mode and the dialog reopens on it rather than
61- * on a default that would drop the credential's role, secret, or certificate.
73+ * reconnect reads the stored secret's mode (and a Microsoft app credential's cloud) and
74+ * the dialog reopens on it rather than on a default that would drop the credential's
75+ * role, secret, certificate, or cloud.
6276 */
63- const STORED_AUTH_TYPE : {
64- [ P in WorkloadIdentityProvider ] : (
65- decrypted : string
66- ) => WorkloadIdentityProviderAuthType < P > | undefined
77+ const STORED_RECONNECT_FIELDS : {
78+ [ P in WorkloadIdentityProvider ] : ( decrypted : string ) => StoredReconnectFields < P >
6779} = {
68- aws : storedAwsAuthType ,
69- databricks : storedDatabricksAuthType ,
70- snowflake : storedSnowflakeAuthType ,
71- microsoft : storedMicrosoftAppAuthType ,
72- google : ( decrypted ) =>
73- isGoogleWorkloadIdentitySecret ( decrypted ) ? 'workload_identity' : 'json_key' ,
80+ aws : authTypeOnly ( storedAwsAuthType ) ,
81+ databricks : authTypeOnly ( storedDatabricksAuthType ) ,
82+ snowflake : authTypeOnly ( storedSnowflakeAuthType ) ,
83+ microsoft : storedMicrosoftAppReconnectFields ,
84+ google : ( decrypted ) => ( {
85+ authType : isGoogleWorkloadIdentitySecret ( decrypted ) ? 'workload_identity' : 'json_key' ,
86+ } ) ,
7487}
7588
7689/**
@@ -99,11 +112,10 @@ async function storedReconnectFields(
99112 return { }
100113 }
101114 const { decrypted } = await decryptSecret ( row . encryptedServiceAccountKey )
102- const reconnectAuthType = STORED_AUTH_TYPE [ provider ] ( decrypted )
103- const reconnectCloud = provider === 'microsoft' ? storedMicrosoftAppCloud ( decrypted ) : undefined
115+ const { authType, cloud } = STORED_RECONNECT_FIELDS [ provider ] ( decrypted )
104116 return {
105- ...( reconnectAuthType ? { reconnectAuthType } : { } ) ,
106- ...( reconnectCloud ? { reconnectCloud } : { } ) ,
117+ ...( authType ? { reconnectAuthType : authType } : { } ) ,
118+ ...( cloud ? { reconnectCloud : cloud } : { } ) ,
107119 }
108120}
109121
0 commit comments