@openinc/parse-server-opendash 3.9.8 → 3.10.1
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.
|
@@ -9,26 +9,81 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
|
9
9
|
const jwks_rsa_1 = __importDefault(require("jwks-rsa"));
|
|
10
10
|
const config_1 = require("../features/config");
|
|
11
11
|
const types_1 = require("../types");
|
|
12
|
-
const tenantId = config_1.ConfigInstance.getInstance().get("MICROSOFT_TENANT_ID")
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const tenantId = config_1.ConfigInstance.getInstance().get("MICROSOFT_TENANT_ID") ||
|
|
13
|
+
process.env.MICROSOFT_TENANT_ID ||
|
|
14
|
+
process.env.OI_MICROSOFT_TENANT_ID;
|
|
15
|
+
const appId = config_1.ConfigInstance.getInstance().get("MICROSOFT_APP_ID") ||
|
|
16
|
+
process.env.MICROSOFT_APP_ID ||
|
|
17
|
+
process.env.OI_MICROSOFT_APP_ID;
|
|
18
|
+
// Setup JWKS client for Microsoft - try v2.0 first, fallback to v1.0
|
|
19
|
+
const getJwksUri = (version = "v2.0") => `https://login.microsoftonline.com/${tenantId}/discovery/${version}/keys`;
|
|
15
20
|
const client = (0, jwks_rsa_1.default)({
|
|
16
|
-
jwksUri:
|
|
21
|
+
jwksUri: getJwksUri(),
|
|
22
|
+
cache: true,
|
|
23
|
+
cacheMaxEntries: 5,
|
|
24
|
+
cacheMaxAge: 1000 * 60 * 60 * 24, // 24 hours
|
|
25
|
+
timeout: 30000, // 30 seconds
|
|
26
|
+
});
|
|
27
|
+
// Fallback client for v1.0 if v2.0 fails
|
|
28
|
+
const clientV1 = (0, jwks_rsa_1.default)({
|
|
29
|
+
jwksUri: getJwksUri("v1.0"),
|
|
30
|
+
cache: true,
|
|
31
|
+
cacheMaxEntries: 5,
|
|
32
|
+
cacheMaxAge: 1000 * 60 * 60 * 24, // 24 hours
|
|
33
|
+
timeout: 30000, // 30 seconds
|
|
17
34
|
});
|
|
18
35
|
function getKey(header, callback) {
|
|
36
|
+
console.log("JWT Header:", header);
|
|
37
|
+
console.log("Tenant ID:", tenantId);
|
|
38
|
+
console.log("App ID:", appId);
|
|
19
39
|
if (!header.kid) {
|
|
40
|
+
console.error("No kid found in token header");
|
|
20
41
|
return callback(new Error("No kid found in token header"));
|
|
21
42
|
}
|
|
43
|
+
console.log("Attempting to get signing key for kid:", header.kid);
|
|
22
44
|
client.getSigningKey(header.kid, (err, key) => {
|
|
23
|
-
if (err
|
|
24
|
-
|
|
45
|
+
if (err) {
|
|
46
|
+
console.error("Error with v2.0 endpoint, trying v1.0:", err);
|
|
47
|
+
// Try v1.0 endpoint as fallback
|
|
48
|
+
clientV1.getSigningKey(header.kid, (errV1, keyV1) => {
|
|
49
|
+
if (errV1) {
|
|
50
|
+
console.error("Error with v1.0 endpoint:", errV1);
|
|
51
|
+
return callback(errV1);
|
|
52
|
+
}
|
|
53
|
+
if (!keyV1) {
|
|
54
|
+
console.error("No key returned from v1.0 JWKS client");
|
|
55
|
+
return callback(new Error("Key not found in v1.0 endpoint"));
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const signingKey = keyV1.getPublicKey();
|
|
59
|
+
console.log("Successfully retrieved signing key from v1.0 endpoint");
|
|
60
|
+
callback(null, signingKey);
|
|
61
|
+
}
|
|
62
|
+
catch (keyError) {
|
|
63
|
+
console.error("Error extracting public key from v1.0:", keyError);
|
|
64
|
+
callback(keyError instanceof Error ? keyError : new Error(String(keyError)));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!key) {
|
|
70
|
+
console.error("No key returned from JWKS client");
|
|
71
|
+
return callback(new Error("Key not found"));
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const signingKey = key.getPublicKey();
|
|
75
|
+
console.log("Successfully retrieved signing key");
|
|
76
|
+
callback(null, signingKey);
|
|
77
|
+
}
|
|
78
|
+
catch (keyError) {
|
|
79
|
+
console.error("Error extracting public key:", keyError);
|
|
80
|
+
callback(keyError instanceof Error ? keyError : new Error(String(keyError)));
|
|
25
81
|
}
|
|
26
|
-
const signingKey = key.getPublicKey();
|
|
27
|
-
callback(null, signingKey);
|
|
28
82
|
});
|
|
29
83
|
}
|
|
30
84
|
async function init(name) {
|
|
31
85
|
Parse.Cloud.define(name, async (request) => {
|
|
86
|
+
console.log("Logging in with microsoft...");
|
|
32
87
|
const token = request.params.token;
|
|
33
88
|
const account = request.params.account;
|
|
34
89
|
const defaultTenant = await new Parse.Query(types_1.Tenant)
|
|
@@ -37,13 +92,49 @@ async function init(name) {
|
|
|
37
92
|
if (!token) {
|
|
38
93
|
throw new Parse.Error(Parse.Error.INVALID_JSON, "Token missing");
|
|
39
94
|
}
|
|
95
|
+
// Validate Microsoft configuration
|
|
96
|
+
if (!tenantId || !appId) {
|
|
97
|
+
console.error("Missing Microsoft configuration:", {
|
|
98
|
+
tenantId: !!tenantId,
|
|
99
|
+
appId: !!appId,
|
|
100
|
+
});
|
|
101
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, "Microsoft authentication not properly configured");
|
|
102
|
+
}
|
|
40
103
|
const verifiedPayload = await new Promise((resolve, reject) => {
|
|
104
|
+
console.log("Starting JWT verification...");
|
|
105
|
+
console.log("Token length:", token.length);
|
|
106
|
+
console.log("Expected audience:", appId);
|
|
107
|
+
console.log("Expected issuer:", `https://login.microsoftonline.com/${tenantId}/v2.0`);
|
|
108
|
+
// Decode token payload for debugging (without verification)
|
|
109
|
+
try {
|
|
110
|
+
const tokenParts = token.split(".");
|
|
111
|
+
if (tokenParts.length === 3) {
|
|
112
|
+
const header = JSON.parse(Buffer.from(tokenParts[0], "base64").toString());
|
|
113
|
+
const payload = JSON.parse(Buffer.from(tokenParts[1], "base64").toString());
|
|
114
|
+
console.log("Token header (unverified):", header);
|
|
115
|
+
console.log("Token payload (unverified):", {
|
|
116
|
+
aud: payload.aud,
|
|
117
|
+
iss: payload.iss,
|
|
118
|
+
tid: payload.tid,
|
|
119
|
+
ver: payload.ver,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (decodeError) {
|
|
124
|
+
console.error("Failed to decode token for debugging:", decodeError);
|
|
125
|
+
}
|
|
41
126
|
jsonwebtoken_1.default.verify(token, getKey, {
|
|
42
127
|
audience: appId,
|
|
43
128
|
issuer: `https://login.microsoftonline.com/${tenantId}/v2.0`,
|
|
129
|
+
algorithms: ["RS256"], // Microsoft uses RS256
|
|
44
130
|
}, (err, decoded) => {
|
|
45
|
-
if (err)
|
|
131
|
+
if (err) {
|
|
132
|
+
console.error("JWT verification failed:", err);
|
|
133
|
+
console.error("Error name:", err.name);
|
|
134
|
+
console.error("Error message:", err.message);
|
|
46
135
|
return reject(err);
|
|
136
|
+
}
|
|
137
|
+
console.log("JWT verification successful");
|
|
47
138
|
resolve(decoded);
|
|
48
139
|
});
|
|
49
140
|
});
|