UNPKG

@openinc/parse-server-opendash

Version:
101 lines (100 loc) 4.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.init = init; const crypto_1 = require("crypto"); const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); const jwks_rsa_1 = __importDefault(require("jwks-rsa")); const config_1 = require("../features/config"); const types_1 = require("../types"); const tenantId = config_1.ConfigInstance.getInstance().get("MICROSOFT_TENANT_ID") || process.env.MICROSOFT_TENANT_ID || process.env.OI_MICROSOFT_TENANT_ID; const appId = config_1.ConfigInstance.getInstance().get("MICROSOFT_APP_ID") || process.env.MICROSOFT_APP_ID || process.env.OI_MICROSOFT_APP_ID; // Simple, standard Microsoft v2.0 endpoint with app-specific parameter const client = (0, jwks_rsa_1.default)({ jwksUri: `https://login.microsoftonline.com/${tenantId}/discovery/keys?appid=${appId}`, cache: true, cacheMaxAge: 12 * 60 * 60 * 1000, // 12 hours timeout: 30000, }); function getKey(header, callback) { if (!header.kid) { return callback(new Error("No kid found in token header")); } client.getSigningKey(header.kid, (err, key) => { if (err) return callback(err); if (!key) return callback(new Error("Key not found")); callback(null, key.getPublicKey()); }); } async function init(name) { Parse.Cloud.define(name, async (request) => { const token = request.params.token; const account = request.params.account; if (!token) { throw new Parse.Error(Parse.Error.INVALID_JSON, "Token missing"); } if (!tenantId || !appId) { throw new Parse.Error(Parse.Error.INVALID_JSON, "Microsoft authentication not properly configured"); } // DEBUGGING: Decode token without verification to see what we're dealing with console.log("=== DEBUGGING TOKEN ==="); try { const tokenParts = token.split("."); const payload = JSON.parse(Buffer.from(tokenParts[1], "base64").toString()); console.log("Token audience (aud):", payload.aud); console.log("Token issuer (iss):", payload.iss); console.log("Expected audience:", appId); console.log("Expected issuer:", `https://login.microsoftonline.com/${tenantId}/v2.0`); console.log("Audience match:", payload.aud === appId); console.log("Issuer match:", payload.iss === `https://login.microsoftonline.com/${tenantId}/v2.0`); } catch (e) { console.error("Failed to decode token:", e); } console.log("=== END DEBUGGING ==="); const verifiedPayload = await new Promise((resolve, reject) => { jsonwebtoken_1.default.verify(token, getKey, { audience: appId, issuer: `https://login.microsoftonline.com/${tenantId}/v2.0`, algorithms: ["RS256"], }, (err, decoded) => { if (err) { console.error("JWT verification failed:", err.message); return reject(err); } resolve(decoded); }); }); const defaultTenant = await new Parse.Query(types_1.Tenant) .ascending("createdAt") .first({ useMasterKey: true }); let user = await new Parse.Query(Parse.User) .equalTo("username", verifiedPayload.oid) .first({ useMasterKey: true }); if (!user) { user = new Parse.User(); user.set("username", verifiedPayload.oid); user.set("email", account.username); user.set("password", (0, crypto_1.randomBytes)(16).toString("hex")); user.set("name", verifiedPayload.name || verifiedPayload.preferred_username); user.set("tenant", defaultTenant); user = await user.signUp(null, { useMasterKey: true }); return user.getSessionToken(); } const sessionToken = "r:" + (0, crypto_1.randomBytes)(16).toString("hex"); const session = new Parse.Object("_Session"); session.set("user", user); session.set("sessionToken", sessionToken); session.set("expiresAt", new Date(Date.now() + 24 * 60 * 60 * 1000 * 7)); const savedSession = await session.save(null, { useMasterKey: true }); return savedSession.get("sessionToken"); }); }