@tdacorp/identity-client 0.2.2 → 0.2.4
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/dist/{chunk-TTFIPEZ3.js → chunk-HO6U23GY.js} +36 -13
- package/dist/index.cjs +36 -13
- package/dist/index.js +1 -1
- package/dist/next.cjs +35 -12
- package/dist/next.js +1 -1
- package/package.json +2 -2
|
@@ -31,23 +31,36 @@ function assertHttps(url, label) {
|
|
|
31
31
|
throw new Error(`Discovery: ${label} "${url}" must be https (loopback hosts are the only http exception)`);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
var ENDPOINT_FIELDS = [
|
|
35
|
+
{ field: "jwks_uri", required: true },
|
|
36
|
+
{ field: "token_endpoint", required: true },
|
|
37
|
+
{ field: "authorization_endpoint", required: true },
|
|
38
|
+
{ field: "userinfo_endpoint", required: false },
|
|
39
|
+
{ field: "end_session_endpoint", required: false },
|
|
40
|
+
{ field: "revocation_endpoint", required: false },
|
|
41
|
+
{ field: "introspection_endpoint", required: false },
|
|
42
|
+
{ field: "registration_endpoint", required: false }
|
|
43
|
+
];
|
|
44
|
+
function validateEndpointField(field, url, issuerOrigin) {
|
|
45
|
+
assertHttps(url, field);
|
|
46
|
+
if (new URL(url).origin !== issuerOrigin) {
|
|
47
|
+
throw new Error(`Discovery: ${field} "${url}" is not same-origin as issuer`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
34
50
|
function validateDiscoveryDocument(document, issuerUrl) {
|
|
35
51
|
assertHttps(issuerUrl, "issuer");
|
|
36
|
-
assertHttps(document.jwks_uri, "jwks_uri");
|
|
37
|
-
assertHttps(document.token_endpoint, "token_endpoint");
|
|
38
|
-
assertHttps(document.authorization_endpoint, "authorization_endpoint");
|
|
39
52
|
if (document.issuer !== issuerUrl) {
|
|
40
53
|
throw new Error(`Discovery: document issuer "${document.issuer}" does not match the configured issuer "${issuerUrl}"`);
|
|
41
54
|
}
|
|
42
55
|
const issuerOrigin = new URL(issuerUrl).origin;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
for (const { field, required } of ENDPOINT_FIELDS) {
|
|
57
|
+
const value = document[field];
|
|
58
|
+
if (value === void 0 && !required) continue;
|
|
59
|
+
if (typeof value !== "string") {
|
|
60
|
+
const requirement = required ? "is required and must be a string" : ", if present, must be a string";
|
|
61
|
+
throw new Error(`Discovery: ${field} ${requirement}`);
|
|
62
|
+
}
|
|
63
|
+
validateEndpointField(field, value, issuerOrigin);
|
|
51
64
|
}
|
|
52
65
|
}
|
|
53
66
|
async function fetchDiscovery(issuerUrl) {
|
|
@@ -129,6 +142,16 @@ var TokenRequestError = class extends Error {
|
|
|
129
142
|
this.errorDescription = details.errorDescription;
|
|
130
143
|
}
|
|
131
144
|
};
|
|
145
|
+
async function fetchDiscoveryForTokenRequest(issuer) {
|
|
146
|
+
try {
|
|
147
|
+
return await fetchDiscovery(issuer);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
throw new TokenRequestError({
|
|
150
|
+
error: "discovery_failed",
|
|
151
|
+
errorDescription: error instanceof Error ? error.message : "Failed to fetch the issuer's discovery document"
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
132
155
|
function toTokenSet(body) {
|
|
133
156
|
return {
|
|
134
157
|
accessToken: body.access_token,
|
|
@@ -159,7 +182,7 @@ async function readTokenResponseBody(response) {
|
|
|
159
182
|
return await response.json().catch(() => null);
|
|
160
183
|
}
|
|
161
184
|
async function exchangeAuthorizationCode(options) {
|
|
162
|
-
const discovery = await
|
|
185
|
+
const discovery = await fetchDiscoveryForTokenRequest(options.issuer);
|
|
163
186
|
const response = await postTokenRequest(
|
|
164
187
|
discovery.token_endpoint,
|
|
165
188
|
options.clientId,
|
|
@@ -179,7 +202,7 @@ async function exchangeAuthorizationCode(options) {
|
|
|
179
202
|
return toTokenSet(body);
|
|
180
203
|
}
|
|
181
204
|
async function clientCredentialsGrant(options) {
|
|
182
|
-
const discovery = await
|
|
205
|
+
const discovery = await fetchDiscoveryForTokenRequest(options.issuer);
|
|
183
206
|
const response = await postTokenRequest(
|
|
184
207
|
discovery.token_endpoint,
|
|
185
208
|
options.clientId,
|
package/dist/index.cjs
CHANGED
|
@@ -68,23 +68,36 @@ function assertHttps(url, label) {
|
|
|
68
68
|
throw new Error(`Discovery: ${label} "${url}" must be https (loopback hosts are the only http exception)`);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
var ENDPOINT_FIELDS = [
|
|
72
|
+
{ field: "jwks_uri", required: true },
|
|
73
|
+
{ field: "token_endpoint", required: true },
|
|
74
|
+
{ field: "authorization_endpoint", required: true },
|
|
75
|
+
{ field: "userinfo_endpoint", required: false },
|
|
76
|
+
{ field: "end_session_endpoint", required: false },
|
|
77
|
+
{ field: "revocation_endpoint", required: false },
|
|
78
|
+
{ field: "introspection_endpoint", required: false },
|
|
79
|
+
{ field: "registration_endpoint", required: false }
|
|
80
|
+
];
|
|
81
|
+
function validateEndpointField(field, url, issuerOrigin) {
|
|
82
|
+
assertHttps(url, field);
|
|
83
|
+
if (new URL(url).origin !== issuerOrigin) {
|
|
84
|
+
throw new Error(`Discovery: ${field} "${url}" is not same-origin as issuer`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
71
87
|
function validateDiscoveryDocument(document, issuerUrl) {
|
|
72
88
|
assertHttps(issuerUrl, "issuer");
|
|
73
|
-
assertHttps(document.jwks_uri, "jwks_uri");
|
|
74
|
-
assertHttps(document.token_endpoint, "token_endpoint");
|
|
75
|
-
assertHttps(document.authorization_endpoint, "authorization_endpoint");
|
|
76
89
|
if (document.issuer !== issuerUrl) {
|
|
77
90
|
throw new Error(`Discovery: document issuer "${document.issuer}" does not match the configured issuer "${issuerUrl}"`);
|
|
78
91
|
}
|
|
79
92
|
const issuerOrigin = new URL(issuerUrl).origin;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
for (const { field, required } of ENDPOINT_FIELDS) {
|
|
94
|
+
const value = document[field];
|
|
95
|
+
if (value === void 0 && !required) continue;
|
|
96
|
+
if (typeof value !== "string") {
|
|
97
|
+
const requirement = required ? "is required and must be a string" : ", if present, must be a string";
|
|
98
|
+
throw new Error(`Discovery: ${field} ${requirement}`);
|
|
99
|
+
}
|
|
100
|
+
validateEndpointField(field, value, issuerOrigin);
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
async function fetchDiscovery(issuerUrl) {
|
|
@@ -166,6 +179,16 @@ var TokenRequestError = class extends Error {
|
|
|
166
179
|
this.errorDescription = details.errorDescription;
|
|
167
180
|
}
|
|
168
181
|
};
|
|
182
|
+
async function fetchDiscoveryForTokenRequest(issuer) {
|
|
183
|
+
try {
|
|
184
|
+
return await fetchDiscovery(issuer);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throw new TokenRequestError({
|
|
187
|
+
error: "discovery_failed",
|
|
188
|
+
errorDescription: error instanceof Error ? error.message : "Failed to fetch the issuer's discovery document"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
169
192
|
function toTokenSet(body) {
|
|
170
193
|
return {
|
|
171
194
|
accessToken: body.access_token,
|
|
@@ -196,7 +219,7 @@ async function readTokenResponseBody(response) {
|
|
|
196
219
|
return await response.json().catch(() => null);
|
|
197
220
|
}
|
|
198
221
|
async function exchangeAuthorizationCode(options) {
|
|
199
|
-
const discovery = await
|
|
222
|
+
const discovery = await fetchDiscoveryForTokenRequest(options.issuer);
|
|
200
223
|
const response = await postTokenRequest(
|
|
201
224
|
discovery.token_endpoint,
|
|
202
225
|
options.clientId,
|
|
@@ -216,7 +239,7 @@ async function exchangeAuthorizationCode(options) {
|
|
|
216
239
|
return toTokenSet(body);
|
|
217
240
|
}
|
|
218
241
|
async function clientCredentialsGrant(options) {
|
|
219
|
-
const discovery = await
|
|
242
|
+
const discovery = await fetchDiscoveryForTokenRequest(options.issuer);
|
|
220
243
|
const response = await postTokenRequest(
|
|
221
244
|
discovery.token_endpoint,
|
|
222
245
|
options.clientId,
|
package/dist/index.js
CHANGED
package/dist/next.cjs
CHANGED
|
@@ -59,23 +59,36 @@ function assertHttps(url, label) {
|
|
|
59
59
|
throw new Error(`Discovery: ${label} "${url}" must be https (loopback hosts are the only http exception)`);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
var ENDPOINT_FIELDS = [
|
|
63
|
+
{ field: "jwks_uri", required: true },
|
|
64
|
+
{ field: "token_endpoint", required: true },
|
|
65
|
+
{ field: "authorization_endpoint", required: true },
|
|
66
|
+
{ field: "userinfo_endpoint", required: false },
|
|
67
|
+
{ field: "end_session_endpoint", required: false },
|
|
68
|
+
{ field: "revocation_endpoint", required: false },
|
|
69
|
+
{ field: "introspection_endpoint", required: false },
|
|
70
|
+
{ field: "registration_endpoint", required: false }
|
|
71
|
+
];
|
|
72
|
+
function validateEndpointField(field, url, issuerOrigin) {
|
|
73
|
+
assertHttps(url, field);
|
|
74
|
+
if (new URL(url).origin !== issuerOrigin) {
|
|
75
|
+
throw new Error(`Discovery: ${field} "${url}" is not same-origin as issuer`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
62
78
|
function validateDiscoveryDocument(document, issuerUrl) {
|
|
63
79
|
assertHttps(issuerUrl, "issuer");
|
|
64
|
-
assertHttps(document.jwks_uri, "jwks_uri");
|
|
65
|
-
assertHttps(document.token_endpoint, "token_endpoint");
|
|
66
|
-
assertHttps(document.authorization_endpoint, "authorization_endpoint");
|
|
67
80
|
if (document.issuer !== issuerUrl) {
|
|
68
81
|
throw new Error(`Discovery: document issuer "${document.issuer}" does not match the configured issuer "${issuerUrl}"`);
|
|
69
82
|
}
|
|
70
83
|
const issuerOrigin = new URL(issuerUrl).origin;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
for (const { field, required } of ENDPOINT_FIELDS) {
|
|
85
|
+
const value = document[field];
|
|
86
|
+
if (value === void 0 && !required) continue;
|
|
87
|
+
if (typeof value !== "string") {
|
|
88
|
+
const requirement = required ? "is required and must be a string" : ", if present, must be a string";
|
|
89
|
+
throw new Error(`Discovery: ${field} ${requirement}`);
|
|
90
|
+
}
|
|
91
|
+
validateEndpointField(field, value, issuerOrigin);
|
|
79
92
|
}
|
|
80
93
|
}
|
|
81
94
|
async function fetchDiscovery(issuerUrl) {
|
|
@@ -157,6 +170,16 @@ var TokenRequestError = class extends Error {
|
|
|
157
170
|
this.errorDescription = details.errorDescription;
|
|
158
171
|
}
|
|
159
172
|
};
|
|
173
|
+
async function fetchDiscoveryForTokenRequest(issuer) {
|
|
174
|
+
try {
|
|
175
|
+
return await fetchDiscovery(issuer);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
throw new TokenRequestError({
|
|
178
|
+
error: "discovery_failed",
|
|
179
|
+
errorDescription: error instanceof Error ? error.message : "Failed to fetch the issuer's discovery document"
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
160
183
|
function toTokenSet(body) {
|
|
161
184
|
return {
|
|
162
185
|
accessToken: body.access_token,
|
|
@@ -187,7 +210,7 @@ async function readTokenResponseBody(response) {
|
|
|
187
210
|
return await response.json().catch(() => null);
|
|
188
211
|
}
|
|
189
212
|
async function exchangeAuthorizationCode(options) {
|
|
190
|
-
const discovery = await
|
|
213
|
+
const discovery = await fetchDiscoveryForTokenRequest(options.issuer);
|
|
191
214
|
const response = await postTokenRequest(
|
|
192
215
|
discovery.token_endpoint,
|
|
193
216
|
options.clientId,
|
package/dist/next.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tdacorp/identity-client",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "OIDC relying-party client for TDACorp Identity: discovery, PKCE, token exchange, token verification and Next.js route helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
],
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"jose": "^6.2.9",
|
|
58
|
-
"@tdacorp/identity-authz": "^0.2.
|
|
58
|
+
"@tdacorp/identity-authz": "^0.2.1"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"next": ">=14"
|