@sphereon/ssi-sdk.ms-authenticator 0.13.1-next.3 → 0.13.1-next.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ---
10
10
 
11
- **Warning: This package still is in every early development. Breaking changes without notice will happen at this point!**
11
+ **Warning: This package still is in early development. Breaking changes without notice will happen at this point!**
12
12
 
13
13
  ---
14
14
 
@@ -19,11 +19,11 @@ A SSI-SDK plugin to authenticate using the Microsoft Authentication Library (MSA
19
19
  ### Installation
20
20
 
21
21
  ```shell
22
- yarn add @sphereon/ssi-sdk.ms-authenticator
22
+ pnpm add @sphereon/ssi-sdk.ms-authenticator
23
23
  ```
24
24
 
25
25
  ### Build
26
26
 
27
27
  ```shell
28
- yarn build
28
+ pnpm build
29
29
  ```
@@ -1,22 +1,33 @@
1
- import { IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index';
2
- export declare const MS_IDENTITY_HOST_NAME_NONE_EU = "https://beta.did.msidentity.com/v1.0/";
3
- export declare const MS_IDENTITY_HOST_NAME_EU = "https://beta.eu.did.msidentity.com/v1.0/";
4
- export declare function checkMsIdentityHostname(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string>;
1
+ import { AuthenticationResult, ConfidentialClientApplication } from '@azure/msal-node';
2
+ import { IMSClientCredentialAuthInfo, IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index';
3
+ export declare const MS_DID_ENDPOINT_NON_EU = "https://beta.did.msidentity.com/v1.0/";
4
+ export declare const MS_DID_ENDPOINT_EU = "https://beta.eu.did.msidentity.com/v1.0/";
5
+ export declare function getMSOpenIDClientRegion(azTenantId: string): Promise<string>;
6
+ export declare function getEntraDIDEndpoint(opts: {
7
+ region?: string;
8
+ azTenantId: string;
9
+ }): Promise<"https://beta.did.msidentity.com/v1.0/" | "https://beta.eu.did.msidentity.com/v1.0/">;
10
+ export declare function assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string>;
5
11
  /**
6
12
  * necessary fields are:
7
13
  * azClientId: clientId of the application you're trying to login
8
14
  * azClientSecret: secret of the application you're trying to login
9
15
  * azTenantId: your MS Azure tenantId
16
+ * optional fields:
10
17
  * credentialManifest: address of your credential manifest. usually in following format:
11
18
  * https://beta.eu.did.msidentity.com/v1.0/<tenant_id>/verifiableCredential/contracts/<verifiable_credential_schema>
12
19
  * @param authenticationArgs
13
20
  * @constructor
14
21
  */
15
- export declare function ClientCredentialAuthenticator(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string>;
22
+ export declare function getMSClientCredentialAccessToken(authenticationArgs: IMsAuthenticationClientCredentialArgs, opts?: {
23
+ confidentialClient?: ConfidentialClientApplication;
24
+ }): Promise<AuthenticationResult>;
25
+ export declare function newMSClientCredentialAuthenticator(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<IMSClientCredentialAuthInfo>;
16
26
  /**
17
27
  * Logs in with provided authenticationArgs and returns access token
18
28
  * @param authenticationArgs
19
29
  * @constructor
20
30
  */
21
31
  export declare function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthenticationUsernamePasswordArgs): Promise<string>;
32
+ export declare function determineMSAuthId(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): string;
22
33
  //# sourceMappingURL=MsAuthenticator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MsAuthenticator.d.ts","sourceRoot":"","sources":["../../src/authenticators/MsAuthenticator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qCAAqC,EAAE,qCAAqC,EAAE,MAAM,UAAU,CAAA;AASvG,eAAO,MAAM,6BAA6B,0CAA0C,CAAA;AACpF,eAAO,MAAM,wBAAwB,6CAA6C,CAAA;AAmBlF,wBAAsB,uBAAuB,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxH;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC,CAmC9H;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB9H"}
1
+ {"version":3,"file":"MsAuthenticator.d.ts","sourceRoot":"","sources":["../../src/authenticators/MsAuthenticator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAM9B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,2BAA2B,EAAE,qCAAqC,EAAE,qCAAqC,EAAE,MAAM,UAAU,CAAA;AAUpI,eAAO,MAAM,sBAAsB,0CAA0C,CAAA;AAC7E,eAAO,MAAM,kBAAkB,6CAA6C,CAAA;AAU5E,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMjF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,iGAGtF;AAED,wBAAsB,+CAA+C,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC,CAOhJ;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gCAAgC,CACpD,kBAAkB,EAAE,qCAAqC,EACzD,IAAI,CAAC,EAAE;IACL,kBAAkB,CAAC,EAAE,6BAA6B,CAAA;CACnD,GACA,OAAO,CAAC,oBAAoB,CAAC,CA6B/B;AAED,wBAAsB,kCAAkC,CACtD,kBAAkB,EAAE,qCAAqC,GACxD,OAAO,CAAC,2BAA2B,CAAC,CAkBtC;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC,CAa9H;AAUD,wBAAgB,iBAAiB,CAAC,kBAAkB,EAAE,qCAAqC,GAAG,qCAAqC,GAAG,MAAM,CAE3I"}
@@ -8,81 +8,88 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.UsernamePasswordAuthenticator = exports.ClientCredentialAuthenticator = exports.checkMsIdentityHostname = exports.MS_IDENTITY_HOST_NAME_EU = exports.MS_IDENTITY_HOST_NAME_NONE_EU = void 0;
15
+ exports.determineMSAuthId = exports.UsernamePasswordAuthenticator = exports.newMSClientCredentialAuthenticator = exports.getMSClientCredentialAccessToken = exports.assertEntraCredentialManifestUrlInCorrectRegion = exports.getEntraDIDEndpoint = exports.getMSOpenIDClientRegion = exports.MS_DID_ENDPOINT_EU = exports.MS_DID_ENDPOINT_NON_EU = void 0;
13
16
  const msal_node_1 = require("@azure/msal-node");
14
17
  const cross_fetch_1 = require("cross-fetch");
18
+ const object_hash_1 = __importDefault(require("object-hash"));
15
19
  const EU = 'EU';
16
20
  const HTTP_METHOD_GET = 'GET';
17
- // Event though there are many regions, MS has only 2 identity host names (EU and NONE_EU)
21
+ // Event though there are many regions, MS has only 2 DID identity host names (EU and NON_EU)
18
22
  // https://docs.microsoft.com/en-us/azure/active-directory/verifiable-credentials/whats-new#are-there-any-changes-to-the-way-that-we-use-the-request-api-as-a-result-of-this-move
19
- exports.MS_IDENTITY_HOST_NAME_NONE_EU = 'https://beta.did.msidentity.com/v1.0/';
20
- exports.MS_IDENTITY_HOST_NAME_EU = 'https://beta.eu.did.msidentity.com/v1.0/';
23
+ exports.MS_DID_ENDPOINT_NON_EU = 'https://beta.did.msidentity.com/v1.0/';
24
+ exports.MS_DID_ENDPOINT_EU = 'https://beta.eu.did.msidentity.com/v1.0/';
21
25
  const MS_LOGIN_PREFIX = 'https://login.microsoftonline.com/';
22
26
  const MS_LOGIN_OPENID_CONFIG_POSTFIX = '/v2.0/.well-known/openid-configuration';
23
27
  const MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE = '3db474b9-6a0c-4840-96ac-1fceb342124f/.default';
24
28
  const ERROR_CREDENTIAL_MANIFEST_REGION = `Error in config file. CredentialManifest URL configured for wrong tenant region. Should start with:`;
25
29
  const ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT = 'Could not acquire verifiableCredentials to access your Azure Key Vault:\n';
26
30
  const ERROR_FAILED_AUTHENTICATION = 'failed to authenticate: ';
27
- function getClientRegion(azTenantId) {
31
+ // todo: This is a pretty heavy operation. Getting all the OIDC discovery data from a fetch only to return the region. Probably wise to add some caching and refactor so we can do more with the other OIDC info as well
32
+ function getMSOpenIDClientRegion(azTenantId) {
28
33
  return __awaiter(this, void 0, void 0, function* () {
29
- let region = EU;
30
- yield (0, cross_fetch_1.fetch)(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET })
34
+ return (0, cross_fetch_1.fetch)(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET })
31
35
  .then((res) => res.json())
32
36
  .then((resp) => __awaiter(this, void 0, void 0, function* () {
33
- region = resp.tenant_region_scope;
37
+ var _a;
38
+ return (_a = resp.tenant_region_scope) !== null && _a !== void 0 ? _a : EU;
34
39
  }));
35
- return region;
36
40
  });
37
41
  }
38
- function checkMsIdentityHostname(authenticationArgs) {
42
+ exports.getMSOpenIDClientRegion = getMSOpenIDClientRegion;
43
+ function getEntraDIDEndpoint(opts) {
44
+ var _a;
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ const region = (_a = opts === null || opts === void 0 ? void 0 : opts.region) !== null && _a !== void 0 ? _a : (yield getMSOpenIDClientRegion(opts.azTenantId));
47
+ return region === EU ? exports.MS_DID_ENDPOINT_EU : exports.MS_DID_ENDPOINT_NON_EU;
48
+ });
49
+ }
50
+ exports.getEntraDIDEndpoint = getEntraDIDEndpoint;
51
+ function assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs) {
52
+ var _a;
39
53
  return __awaiter(this, void 0, void 0, function* () {
40
- const region = authenticationArgs.region ? authenticationArgs.region : yield getClientRegion(authenticationArgs.azTenantId);
41
- const msIdentityHostName = region === EU ? exports.MS_IDENTITY_HOST_NAME_EU : exports.MS_IDENTITY_HOST_NAME_NONE_EU;
54
+ const msDIDEndpoint = yield getEntraDIDEndpoint(authenticationArgs);
42
55
  // Check that the Credential Manifest URL is in the same tenant Region and throw an error if it's not
43
- if (!authenticationArgs.credentialManifestUrl.startsWith(msIdentityHostName)) {
44
- throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msIdentityHostName + `. value: ${authenticationArgs.credentialManifestUrl}`);
56
+ if (!((_a = authenticationArgs.credentialManifestUrl) === null || _a === void 0 ? void 0 : _a.startsWith(msDIDEndpoint))) {
57
+ throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msDIDEndpoint + `. value: ${authenticationArgs.credentialManifestUrl}`);
45
58
  }
46
- return msIdentityHostName;
59
+ return msDIDEndpoint;
47
60
  });
48
61
  }
49
- exports.checkMsIdentityHostname = checkMsIdentityHostname;
62
+ exports.assertEntraCredentialManifestUrlInCorrectRegion = assertEntraCredentialManifestUrlInCorrectRegion;
50
63
  /**
51
64
  * necessary fields are:
52
65
  * azClientId: clientId of the application you're trying to login
53
66
  * azClientSecret: secret of the application you're trying to login
54
67
  * azTenantId: your MS Azure tenantId
68
+ * optional fields:
55
69
  * credentialManifest: address of your credential manifest. usually in following format:
56
70
  * https://beta.eu.did.msidentity.com/v1.0/<tenant_id>/verifiableCredential/contracts/<verifiable_credential_schema>
57
71
  * @param authenticationArgs
58
72
  * @constructor
59
73
  */
60
- function ClientCredentialAuthenticator(authenticationArgs) {
74
+ function getMSClientCredentialAccessToken(authenticationArgs, opts) {
75
+ var _a, _b, _c;
61
76
  return __awaiter(this, void 0, void 0, function* () {
62
- const msalConfig = {
63
- auth: {
64
- clientId: authenticationArgs.azClientId,
65
- authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,
66
- clientSecret: authenticationArgs.azClientSecret,
67
- },
68
- system: {
69
- loggerOptions: {
70
- piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false,
71
- logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : msal_node_1.LogLevel.Verbose,
72
- },
73
- },
74
- };
75
- const cca = new msal_node_1.ConfidentialClientApplication(msalConfig);
77
+ const confidentialClient = (_a = opts === null || opts === void 0 ? void 0 : opts.confidentialClient) !== null && _a !== void 0 ? _a : (yield newMSClientCredentialAuthenticator(authenticationArgs).then((cca) => cca.confidentialClient));
78
+ if (!confidentialClient) {
79
+ throw Error('No Credential Client Authenticator could be constructed');
80
+ }
81
+ if (authenticationArgs === null || authenticationArgs === void 0 ? void 0 : authenticationArgs.credentialManifestUrl) {
82
+ yield assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs);
83
+ }
76
84
  const msalClientCredentialRequest = {
77
- scopes: authenticationArgs.scopes ? authenticationArgs.scopes : [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE],
78
- skipCache: authenticationArgs.skipCache ? authenticationArgs.skipCache : false,
85
+ scopes: (_b = authenticationArgs.scopes) !== null && _b !== void 0 ? _b : ((authenticationArgs === null || authenticationArgs === void 0 ? void 0 : authenticationArgs.credentialManifestUrl) ? [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE] : []),
86
+ skipCache: (_c = authenticationArgs.skipCache) !== null && _c !== void 0 ? _c : false,
79
87
  };
80
- checkMsIdentityHostname(authenticationArgs);
81
88
  // get the Access Token
82
89
  try {
83
- const result = yield cca.acquireTokenByClientCredential(msalClientCredentialRequest);
84
- if (result && result.accessToken) {
85
- return result.accessToken;
90
+ const result = yield confidentialClient.acquireTokenByClientCredential(msalClientCredentialRequest);
91
+ if (result) {
92
+ return result;
86
93
  }
87
94
  }
88
95
  catch (err) {
@@ -90,10 +97,33 @@ function ClientCredentialAuthenticator(authenticationArgs) {
90
97
  error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT + err,
91
98
  };
92
99
  }
93
- return '';
100
+ throw {
101
+ error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT,
102
+ };
94
103
  });
95
104
  }
96
- exports.ClientCredentialAuthenticator = ClientCredentialAuthenticator;
105
+ exports.getMSClientCredentialAccessToken = getMSClientCredentialAccessToken;
106
+ function newMSClientCredentialAuthenticator(authenticationArgs) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ const didEndpoint = (authenticationArgs === null || authenticationArgs === void 0 ? void 0 : authenticationArgs.credentialManifestUrl)
109
+ ? yield assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs)
110
+ : undefined;
111
+ const auth = authOptions(authenticationArgs);
112
+ const id = (0, object_hash_1.default)(auth);
113
+ const msalConfig = {
114
+ auth,
115
+ system: {
116
+ loggerOptions: {
117
+ piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false,
118
+ logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : msal_node_1.LogLevel.Verbose,
119
+ },
120
+ },
121
+ };
122
+ const confidentialClientApp = new msal_node_1.ConfidentialClientApplication(msalConfig);
123
+ return { confidentialClient: confidentialClientApp, msalConfig, authenticationArgs, didEndpoint, id };
124
+ });
125
+ }
126
+ exports.newMSClientCredentialAuthenticator = newMSClientCredentialAuthenticator;
97
127
  /**
98
128
  * Logs in with provided authenticationArgs and returns access token
99
129
  * @param authenticationArgs
@@ -102,10 +132,7 @@ exports.ClientCredentialAuthenticator = ClientCredentialAuthenticator;
102
132
  function UsernamePasswordAuthenticator(authenticationArgs) {
103
133
  return __awaiter(this, void 0, void 0, function* () {
104
134
  const msalConfig = {
105
- auth: {
106
- clientId: authenticationArgs.azClientId,
107
- authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,
108
- },
135
+ auth: authOptions(authenticationArgs),
109
136
  };
110
137
  const pca = new msal_node_1.PublicClientApplication(msalConfig);
111
138
  return yield pca
@@ -119,4 +146,11 @@ function UsernamePasswordAuthenticator(authenticationArgs) {
119
146
  });
120
147
  }
121
148
  exports.UsernamePasswordAuthenticator = UsernamePasswordAuthenticator;
149
+ function authOptions(authenticationArgs) {
150
+ return Object.assign({ clientId: authenticationArgs.azClientId, authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId }, (authenticationArgs && 'azClientSecret' in authenticationArgs && { clientSecret: authenticationArgs.azClientSecret }));
151
+ }
152
+ function determineMSAuthId(authenticationArgs) {
153
+ return (0, object_hash_1.default)(authOptions(authenticationArgs));
154
+ }
155
+ exports.determineMSAuthId = determineMSAuthId;
122
156
  //# sourceMappingURL=MsAuthenticator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MsAuthenticator.js","sourceRoot":"","sources":["../../src/authenticators/MsAuthenticator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MsAuthenticator.js","sourceRoot":"","sources":["../../src/authenticators/MsAuthenticator.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import { IAgentContext } from '@veramo/core';
2
- import { LogLevel } from '@azure/msal-node';
1
+ import { ConfidentialClientApplication, Configuration, LogLevel } from '@azure/msal-node';
3
2
  /**
4
3
  * azClientId: clientId of the application you're trying to login
5
4
  * azClientSecret: secret of the application you're trying to login
@@ -25,7 +24,7 @@ export interface IMsAuthenticationClientCredentialArgs {
25
24
  azClientId: string;
26
25
  azTenantId: string;
27
26
  azClientSecret: string;
28
- credentialManifestUrl: string;
27
+ credentialManifestUrl?: string;
29
28
  authority?: string;
30
29
  region?: string;
31
30
  scopes?: string[];
@@ -51,6 +50,11 @@ export interface IMsAuthenticationUsernamePasswordArgs {
51
50
  username: string;
52
51
  authority?: string;
53
52
  }
54
- export type IRequiredContext = IAgentContext<Record<string, never>>;
55
- export type IMsAuthenticationResponse = String;
53
+ export interface IMSClientCredentialAuthInfo {
54
+ id: string;
55
+ confidentialClient: ConfidentialClientApplication;
56
+ msalConfig: Configuration;
57
+ authenticationArgs: IMsAuthenticationClientCredentialArgs;
58
+ didEndpoint?: string;
59
+ }
56
60
  //# sourceMappingURL=IMsAuthenticator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IMsAuthenticator.d.ts","sourceRoot":"","sources":["../../src/types/IMsAuthenticator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,qCAAqC;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,qCAAqC;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;AACnE,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAA"}
1
+ {"version":3,"file":"IMsAuthenticator.d.ts","sourceRoot":"","sources":["../../src/types/IMsAuthenticator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACzF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,qCAAqC;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,qCAAqC;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,kBAAkB,EAAE,6BAA6B,CAAA;IACjD,UAAU,EAAE,aAAa,CAAA;IACzB,kBAAkB,EAAE,qCAAqC,CAAA;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sphereon/ssi-sdk.ms-authenticator",
3
- "version": "0.13.1-next.3+cf98046",
3
+ "version": "0.13.1-next.32+ba897de",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,16 +9,20 @@
9
9
  "build:clean": "tsc --build --clean && tsc --build"
10
10
  },
11
11
  "dependencies": {
12
- "@azure/msal-common": "^11.0.0",
13
- "@azure/msal-node": "^1.16.0",
14
- "@veramo/core": "4.2.0",
15
- "cross-fetch": "^3.1.5"
12
+ "@azure/msal-common": "^13.2.0",
13
+ "@azure/msal-node": "^1.18.0",
14
+ "cross-fetch": "^3.1.5",
15
+ "object-hash": "^3.0.0"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/jest": "^27.5.2",
19
- "jest": "^27.5.1",
20
- "prettier": "^2.4.1",
21
- "ts-jest": "^27.1.5"
19
+ "@types/object-hash": "^3.0.2",
20
+ "jest": "^29.6.1",
21
+ "prettier": "^2.8.8",
22
+ "ts-jest": "^29.1.1"
23
+ },
24
+ "engines": {
25
+ "node": ">= 16.0"
22
26
  },
23
27
  "files": [
24
28
  "dist/**/*",
@@ -42,5 +46,5 @@
42
46
  "SSI",
43
47
  "Veramo"
44
48
  ],
45
- "gitHead": "cf9804640b7881973e03389e05e5fa4734f107a7"
49
+ "gitHead": "ba897ded1b092dd7d21634cfb0de396a59d2e0d5"
46
50
  }
@@ -1,15 +1,25 @@
1
- import { ConfidentialClientApplication, LogLevel, PublicClientApplication, UsernamePasswordRequest } from '@azure/msal-node'
2
- import { IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index'
1
+ import {
2
+ AuthenticationResult,
3
+ ConfidentialClientApplication,
4
+ Configuration,
5
+ LogLevel,
6
+ NodeAuthOptions,
7
+ PublicClientApplication,
8
+ UsernamePasswordRequest,
9
+ } from '@azure/msal-node'
3
10
  import { fetch } from 'cross-fetch'
11
+ import { IMSClientCredentialAuthInfo, IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index'
12
+
13
+ import hash from 'object-hash'
4
14
 
5
15
  const EU = 'EU'
6
16
 
7
17
  const HTTP_METHOD_GET = 'GET'
8
18
 
9
- // Event though there are many regions, MS has only 2 identity host names (EU and NONE_EU)
19
+ // Event though there are many regions, MS has only 2 DID identity host names (EU and NON_EU)
10
20
  // https://docs.microsoft.com/en-us/azure/active-directory/verifiable-credentials/whats-new#are-there-any-changes-to-the-way-that-we-use-the-request-api-as-a-result-of-this-move
11
- export const MS_IDENTITY_HOST_NAME_NONE_EU = 'https://beta.did.msidentity.com/v1.0/'
12
- export const MS_IDENTITY_HOST_NAME_EU = 'https://beta.eu.did.msidentity.com/v1.0/'
21
+ export const MS_DID_ENDPOINT_NON_EU = 'https://beta.did.msidentity.com/v1.0/'
22
+ export const MS_DID_ENDPOINT_EU = 'https://beta.eu.did.msidentity.com/v1.0/'
13
23
  const MS_LOGIN_PREFIX = 'https://login.microsoftonline.com/'
14
24
  const MS_LOGIN_OPENID_CONFIG_POSTFIX = '/v2.0/.well-known/openid-configuration'
15
25
  const MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE = '3db474b9-6a0c-4840-96ac-1fceb342124f/.default'
@@ -18,24 +28,27 @@ const ERROR_CREDENTIAL_MANIFEST_REGION = `Error in config file. CredentialManife
18
28
  const ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT = 'Could not acquire verifiableCredentials to access your Azure Key Vault:\n'
19
29
  const ERROR_FAILED_AUTHENTICATION = 'failed to authenticate: '
20
30
 
21
- async function getClientRegion(azTenantId: string): Promise<string> {
22
- let region = EU
23
- await fetch(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET })
31
+ // todo: This is a pretty heavy operation. Getting all the OIDC discovery data from a fetch only to return the region. Probably wise to add some caching and refactor so we can do more with the other OIDC info as well
32
+ export async function getMSOpenIDClientRegion(azTenantId: string): Promise<string> {
33
+ return fetch(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET })
24
34
  .then((res) => res.json())
25
35
  .then(async (resp) => {
26
- region = resp.tenant_region_scope
36
+ return resp.tenant_region_scope ?? EU
27
37
  })
28
- return region
29
38
  }
30
39
 
31
- export async function checkMsIdentityHostname(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string> {
32
- const region = authenticationArgs.region ? authenticationArgs.region : await getClientRegion(authenticationArgs.azTenantId)
33
- const msIdentityHostName = region === EU ? MS_IDENTITY_HOST_NAME_EU : MS_IDENTITY_HOST_NAME_NONE_EU
40
+ export async function getEntraDIDEndpoint(opts: { region?: string; azTenantId: string }) {
41
+ const region = opts?.region ?? (await getMSOpenIDClientRegion(opts.azTenantId))
42
+ return region === EU ? MS_DID_ENDPOINT_EU : MS_DID_ENDPOINT_NON_EU
43
+ }
44
+
45
+ export async function assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string> {
46
+ const msDIDEndpoint = await getEntraDIDEndpoint(authenticationArgs)
34
47
  // Check that the Credential Manifest URL is in the same tenant Region and throw an error if it's not
35
- if (!authenticationArgs.credentialManifestUrl.startsWith(msIdentityHostName)) {
36
- throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msIdentityHostName + `. value: ${authenticationArgs.credentialManifestUrl}`)
48
+ if (!authenticationArgs.credentialManifestUrl?.startsWith(msDIDEndpoint)) {
49
+ throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msDIDEndpoint + `. value: ${authenticationArgs.credentialManifestUrl}`)
37
50
  }
38
- return msIdentityHostName
51
+ return msDIDEndpoint
39
52
  }
40
53
 
41
54
  /**
@@ -43,46 +56,68 @@ export async function checkMsIdentityHostname(authenticationArgs: IMsAuthenticat
43
56
  * azClientId: clientId of the application you're trying to login
44
57
  * azClientSecret: secret of the application you're trying to login
45
58
  * azTenantId: your MS Azure tenantId
59
+ * optional fields:
46
60
  * credentialManifest: address of your credential manifest. usually in following format:
47
61
  * https://beta.eu.did.msidentity.com/v1.0/<tenant_id>/verifiableCredential/contracts/<verifiable_credential_schema>
48
62
  * @param authenticationArgs
49
63
  * @constructor
50
64
  */
51
- export async function ClientCredentialAuthenticator(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string> {
52
- const msalConfig = {
53
- auth: {
54
- clientId: authenticationArgs.azClientId,
55
- authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,
56
- clientSecret: authenticationArgs.azClientSecret,
57
- },
58
- system: {
59
- loggerOptions: {
60
- piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false,
61
- logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : LogLevel.Verbose,
62
- },
63
- },
65
+ export async function getMSClientCredentialAccessToken(
66
+ authenticationArgs: IMsAuthenticationClientCredentialArgs,
67
+ opts?: {
68
+ confidentialClient?: ConfidentialClientApplication
69
+ }
70
+ ): Promise<AuthenticationResult> {
71
+ const confidentialClient =
72
+ opts?.confidentialClient ?? (await newMSClientCredentialAuthenticator(authenticationArgs).then((cca) => cca.confidentialClient))
73
+ if (!confidentialClient) {
74
+ throw Error('No Credential Client Authenticator could be constructed')
75
+ }
76
+ if (authenticationArgs?.credentialManifestUrl) {
77
+ await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs)
64
78
  }
65
79
 
66
- const cca = new ConfidentialClientApplication(msalConfig)
67
80
  const msalClientCredentialRequest = {
68
- scopes: authenticationArgs.scopes ? authenticationArgs.scopes : [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE],
69
- skipCache: authenticationArgs.skipCache ? authenticationArgs.skipCache : false,
81
+ scopes: authenticationArgs.scopes ?? (authenticationArgs?.credentialManifestUrl ? [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE] : []),
82
+ skipCache: authenticationArgs.skipCache ?? false,
70
83
  }
71
84
 
72
- checkMsIdentityHostname(authenticationArgs)
73
-
74
85
  // get the Access Token
75
86
  try {
76
- const result = await cca.acquireTokenByClientCredential(msalClientCredentialRequest)
77
- if (result && result.accessToken) {
78
- return result.accessToken
87
+ const result = await confidentialClient.acquireTokenByClientCredential(msalClientCredentialRequest)
88
+ if (result) {
89
+ return result
79
90
  }
80
91
  } catch (err) {
81
92
  throw {
82
93
  error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT + err,
83
94
  }
84
95
  }
85
- return ''
96
+ throw {
97
+ error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT,
98
+ }
99
+ }
100
+
101
+ export async function newMSClientCredentialAuthenticator(
102
+ authenticationArgs: IMsAuthenticationClientCredentialArgs
103
+ ): Promise<IMSClientCredentialAuthInfo> {
104
+ const didEndpoint = authenticationArgs?.credentialManifestUrl
105
+ ? await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs)
106
+ : undefined
107
+ const auth = authOptions(authenticationArgs)
108
+ const id = hash(auth)
109
+ const msalConfig: Configuration = {
110
+ auth,
111
+ system: {
112
+ loggerOptions: {
113
+ piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false,
114
+ logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : LogLevel.Verbose,
115
+ },
116
+ },
117
+ }
118
+ const confidentialClientApp = new ConfidentialClientApplication(msalConfig)
119
+
120
+ return { confidentialClient: confidentialClientApp, msalConfig, authenticationArgs, didEndpoint, id }
86
121
  }
87
122
 
88
123
  /**
@@ -92,10 +127,7 @@ export async function ClientCredentialAuthenticator(authenticationArgs: IMsAuthe
92
127
  */
93
128
  export async function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthenticationUsernamePasswordArgs): Promise<string> {
94
129
  const msalConfig = {
95
- auth: {
96
- clientId: authenticationArgs.azClientId,
97
- authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,
98
- },
130
+ auth: authOptions(authenticationArgs),
99
131
  }
100
132
  const pca = new PublicClientApplication(msalConfig)
101
133
  return await pca
@@ -107,3 +139,15 @@ export async function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthe
107
139
  throw new Error(ERROR_FAILED_AUTHENTICATION + error)
108
140
  })
109
141
  }
142
+
143
+ function authOptions(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): NodeAuthOptions {
144
+ return {
145
+ clientId: authenticationArgs.azClientId,
146
+ authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,
147
+ ...(authenticationArgs && 'azClientSecret' in authenticationArgs && { clientSecret: authenticationArgs.azClientSecret }),
148
+ }
149
+ }
150
+
151
+ export function determineMSAuthId(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): string {
152
+ return hash(authOptions(authenticationArgs))
153
+ }
@@ -1,6 +1,4 @@
1
- import { IAgentContext } from '@veramo/core'
2
- import { LogLevel } from '@azure/msal-node'
3
-
1
+ import { ConfidentialClientApplication, Configuration, LogLevel } from '@azure/msal-node'
4
2
  /**
5
3
  * azClientId: clientId of the application you're trying to login
6
4
  * azClientSecret: secret of the application you're trying to login
@@ -26,7 +24,7 @@ export interface IMsAuthenticationClientCredentialArgs {
26
24
  azClientId: string
27
25
  azTenantId: string
28
26
  azClientSecret: string
29
- credentialManifestUrl: string
27
+ credentialManifestUrl?: string
30
28
  authority?: string
31
29
  region?: string
32
30
  scopes?: string[]
@@ -54,5 +52,10 @@ export interface IMsAuthenticationUsernamePasswordArgs {
54
52
  authority?: string
55
53
  }
56
54
 
57
- export type IRequiredContext = IAgentContext<Record<string, never>>
58
- export type IMsAuthenticationResponse = String
55
+ export interface IMSClientCredentialAuthInfo {
56
+ id: string
57
+ confidentialClient: ConfidentialClientApplication
58
+ msalConfig: Configuration
59
+ authenticationArgs: IMsAuthenticationClientCredentialArgs
60
+ didEndpoint?: string
61
+ }