@telicent-oss/fe-auth-lib 0.0.1-TELFE-1438.0 → 0.0.2
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/package.json +2 -2
- package/src/AuthServerOAuth2Client.js +5 -4
- package/src/schemas.js +44 -40
- package/src/schemas.test.js +13 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telicent-oss/fe-auth-lib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "OAuth2 client library for Telicent Authentication Server",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=20.19.0"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "658932e3799d7e9cbc44e256960c73e071d15abd"
|
|
54
54
|
}
|
|
@@ -34,6 +34,11 @@ class AuthServerOAuth2Client {
|
|
|
34
34
|
`Invalid AuthServerOAuth2Client configuration: ${error.message}`
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
|
+
} else {
|
|
38
|
+
console.warn(
|
|
39
|
+
"⚠️ AuthServerOAuth2Client instantiated with undefined config"
|
|
40
|
+
);
|
|
41
|
+
return;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
this.config = {
|
|
@@ -414,7 +419,6 @@ class AuthServerOAuth2Client {
|
|
|
414
419
|
const result = await response.json();
|
|
415
420
|
// set auth_session_id if user is already signed in
|
|
416
421
|
sessionStorage.setItem("auth_id_token", result.id_token);
|
|
417
|
-
console.log(result);
|
|
418
422
|
return true;
|
|
419
423
|
}
|
|
420
424
|
|
|
@@ -724,9 +728,6 @@ class AuthServerOAuth2Client {
|
|
|
724
728
|
const response = await fetch(url, requestOptions);
|
|
725
729
|
|
|
726
730
|
if (response.status === 401) {
|
|
727
|
-
// QUESTION: would I ever use this method to call session check?
|
|
728
|
-
// I can only envisage scenarios where app endpoints get hit using this?
|
|
729
|
-
//
|
|
730
731
|
// Don't auto-logout during callback flow or logout operations to prevent infinite loops
|
|
731
732
|
const isCallbackFlow =
|
|
732
733
|
options.skipAutoLogout || url.includes("/session/idtoken");
|
package/src/schemas.js
CHANGED
|
@@ -4,11 +4,13 @@ let GetUserInfoSchema;
|
|
|
4
4
|
let AuthServerOAuth2ClientConfigSchema;
|
|
5
5
|
|
|
6
6
|
try {
|
|
7
|
-
if (typeof require !==
|
|
8
|
-
z = require(
|
|
7
|
+
if (typeof require !== "undefined") {
|
|
8
|
+
z = require("zod").z;
|
|
9
9
|
}
|
|
10
10
|
} catch (e) {
|
|
11
|
-
console.warn(
|
|
11
|
+
console.warn(
|
|
12
|
+
"Zod not available in this environment, schema validation will be disabled"
|
|
13
|
+
);
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -17,64 +19,66 @@ try {
|
|
|
17
19
|
*/
|
|
18
20
|
if (z) {
|
|
19
21
|
GetUserInfoSchema = z.object({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
// Core user identity (from JWTConfig.java:169-171)
|
|
23
|
+
sub: z.string(), // Always present
|
|
24
|
+
email: z.string().email(), // NOT NULL in DB
|
|
25
|
+
preferred_name: z.string(), // NOT NULL in DB
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
// Standard OIDC claims (always present)
|
|
28
|
+
iss: z.string(), // Issuer URL
|
|
29
|
+
aud: z.string(), // Audience (client ID)
|
|
30
|
+
exp: z.number(), // Expiration timestamp
|
|
31
|
+
iat: z.number(), // Issued at timestamp
|
|
32
|
+
jti: z.string(), // JWT ID
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// Optional OIDC claims (conditional)
|
|
35
|
+
nonce: z.string().optional(), // Only if sent in auth request
|
|
36
|
+
auth_time: z.number().optional(), // Authentication timestamp
|
|
37
|
+
sid: z.string().optional(), // Session ID
|
|
38
|
+
azp: z.string().optional(), // Authorized party
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
// FE client additions (check your oauth2Client implementation)
|
|
41
|
+
name: z.string().optional(),
|
|
42
|
+
token_expired: z.boolean().optional(),
|
|
43
|
+
token_expires_at: z.string().optional(),
|
|
44
|
+
source: z.string().optional(),
|
|
45
|
+
externalProvider: z.record(z.unknown()).optional(),
|
|
44
46
|
});
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
49
|
* Zod schema for AuthServerOAuth2Client constructor config
|
|
48
50
|
*/
|
|
49
|
-
AuthServerOAuth2ClientConfigSchema = z
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
AuthServerOAuth2ClientConfigSchema = z
|
|
52
|
+
.object({
|
|
53
|
+
// OAuth2 client identifier
|
|
54
|
+
clientId: z.string(),
|
|
55
|
+
authServerUrl: z.string().url(),
|
|
56
|
+
redirectUri: z.string().url(),
|
|
57
|
+
popupRedirectUri: z.string().url(),
|
|
58
|
+
scope: z.string(),
|
|
59
|
+
onLogout: z.function(),
|
|
60
|
+
})
|
|
61
|
+
.strict();
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
// ES module and CommonJS exports
|
|
62
|
-
if (typeof module !==
|
|
65
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
63
66
|
module.exports = {
|
|
64
67
|
GetUserInfoSchema,
|
|
65
|
-
AuthServerOAuth2ClientConfigSchema
|
|
68
|
+
AuthServerOAuth2ClientConfigSchema,
|
|
66
69
|
};
|
|
67
70
|
module.exports.default = {
|
|
68
71
|
GetUserInfoSchema,
|
|
69
|
-
AuthServerOAuth2ClientConfigSchema
|
|
72
|
+
AuthServerOAuth2ClientConfigSchema,
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
if (typeof exports !==
|
|
76
|
+
if (typeof exports !== "undefined" && typeof module === "undefined") {
|
|
74
77
|
exports.GetUserInfoSchema = GetUserInfoSchema;
|
|
75
|
-
exports.AuthServerOAuth2ClientConfigSchema =
|
|
78
|
+
exports.AuthServerOAuth2ClientConfigSchema =
|
|
79
|
+
AuthServerOAuth2ClientConfigSchema;
|
|
76
80
|
exports.default = {
|
|
77
81
|
GetUserInfoSchema,
|
|
78
|
-
AuthServerOAuth2ClientConfigSchema
|
|
82
|
+
AuthServerOAuth2ClientConfigSchema,
|
|
79
83
|
};
|
|
80
84
|
}
|
package/src/schemas.test.js
CHANGED
|
@@ -65,19 +65,19 @@ describe("AuthServerOAuth2ClientConfigSchema", () => {
|
|
|
65
65
|
|
|
66
66
|
expect(results).toMatchInlineSnapshot(`
|
|
67
67
|
[
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"✗ relative slash URL in popupRedirectUri → popupRedirectUri: Invalid url",
|
|
74
|
-
"✗ relative dot-slash URL in popupRedirectUri → popupRedirectUri: Invalid url",
|
|
75
|
-
"✗ URL without protocol in popupRedirectUri → popupRedirectUri: Invalid url",
|
|
76
|
-
"✗ protocol-relative URL in popupRedirectUri → popupRedirectUri: Invalid url",
|
|
77
|
-
"✗ relative URL in authServerUrl → authServerUrl: Invalid url",
|
|
78
|
-
"✗ relative URL in redirectUri → redirectUri: Invalid url",
|
|
79
|
-
"✗ relative URL in apiUrl →
|
|
80
|
-
"✗ unknown property → root: Unrecognized key(s) in object: 'unknownProperty'",
|
|
68
|
+
"✗ absolute https URL → clientId: Required, authServerUrl: Required, redirectUri: Required, scope: Required, onLogout: Required",
|
|
69
|
+
"✗ absolute http URL → clientId: Required, authServerUrl: Required, redirectUri: Required, scope: Required, onLogout: Required",
|
|
70
|
+
"✗ null value → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Expected string, received null, scope: Required, onLogout: Required",
|
|
71
|
+
"✗ omitted field → authServerUrl: Required, redirectUri: Required, popupRedirectUri: Required, scope: Required, onLogout: Required",
|
|
72
|
+
"✗ all fields with absolute URLs → onLogout: Required, root: Unrecognized key(s) in object: 'apiUrl'",
|
|
73
|
+
"✗ relative slash URL in popupRedirectUri → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Invalid url, scope: Required, onLogout: Required",
|
|
74
|
+
"✗ relative dot-slash URL in popupRedirectUri → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Invalid url, scope: Required, onLogout: Required",
|
|
75
|
+
"✗ URL without protocol in popupRedirectUri → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Invalid url, scope: Required, onLogout: Required",
|
|
76
|
+
"✗ protocol-relative URL in popupRedirectUri → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Invalid url, scope: Required, onLogout: Required",
|
|
77
|
+
"✗ relative URL in authServerUrl → clientId: Required, authServerUrl: Invalid url, redirectUri: Required, popupRedirectUri: Required, scope: Required, onLogout: Required",
|
|
78
|
+
"✗ relative URL in redirectUri → clientId: Required, authServerUrl: Required, redirectUri: Invalid url, popupRedirectUri: Required, scope: Required, onLogout: Required",
|
|
79
|
+
"✗ relative URL in apiUrl → clientId: Required, authServerUrl: Required, redirectUri: Required, popupRedirectUri: Required, scope: Required, onLogout: Required, root: Unrecognized key(s) in object: 'apiUrl'",
|
|
80
|
+
"✗ unknown property → authServerUrl: Required, redirectUri: Required, popupRedirectUri: Required, scope: Required, onLogout: Required, root: Unrecognized key(s) in object: 'unknownProperty'",
|
|
81
81
|
]
|
|
82
82
|
`);
|
|
83
83
|
});
|