@linkedmink/passport-mutual-key-challenge
Version:
Implements a Passport strategy to authenticate the public key of a user by issuing a dynamic generated challenge
89 lines • 4.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.challengeByBase64Header = exports.challengeByBase64Body = void 0;
const ChallengeError_1 = require("./Types/ChallengeError");
const challengeByBase64Body = (userIdProperty, challengeProperty, responseProperty = "response") => {
return (req) => {
const body = req.body;
const userId = body[userIdProperty];
if (!userId) {
return new ChallengeError_1.ChallengeError(`The property ${userIdProperty} does not contain the user's key`, ChallengeError_1.ChallengeStage.ClientChallenge);
}
const challenge = body[challengeProperty];
if (challenge) {
const sent = challenge;
return {
userId: userId,
clientRequested: {
message: Buffer.from(sent.message, "base64"),
signature: Buffer.from(sent.signature, "base64"),
},
requestDateTime: new Date(),
};
}
const response = body[responseProperty];
if (response) {
const sent = response;
return {
userId: userId,
clientResponsed: {
message: Buffer.from(sent.message, "base64"),
signature: Buffer.from(sent.signature, "base64"),
},
};
}
return new ChallengeError_1.ChallengeError(`Both ${challengeProperty} and ${responseProperty} does not contain the challenge message`, ChallengeError_1.ChallengeStage.ClientChallenge);
};
};
exports.challengeByBase64Body = challengeByBase64Body;
var KeyRegExIx;
(function (KeyRegExIx) {
KeyRegExIx[KeyRegExIx["Full"] = 0] = "Full";
KeyRegExIx[KeyRegExIx["Value"] = 1] = "Value";
})(KeyRegExIx || (KeyRegExIx = {}));
var ValueRegExIx;
(function (ValueRegExIx) {
ValueRegExIx[ValueRegExIx["Full"] = 0] = "Full";
ValueRegExIx[ValueRegExIx["Challenge"] = 1] = "Challenge";
ValueRegExIx[ValueRegExIx["Response"] = 2] = "Response";
ValueRegExIx[ValueRegExIx["Message"] = 3] = "Message";
ValueRegExIx[ValueRegExIx["Signature"] = 4] = "Signature";
})(ValueRegExIx || (ValueRegExIx = {}));
const challengeByBase64Header = (keyFieldName = "uid", challengeFieldName = "cha", responseFieldName = "res") => {
const MUTUAL_AUTH = "Mutual";
const KEY_REGEX = new RegExp(`(${keyFieldName})=([A-Za-z0-9+/=]+)`, "i");
const CHALLENGE_REGEX = new RegExp(`(${challengeFieldName})|(${responseFieldName})=([A-Za-z0-9+/=]+),([A-Za-z0-9+/=]+)`, "i");
return (req) => {
const authHeader = req.headers["authorization"]?.trim();
if (!authHeader?.startsWith(MUTUAL_AUTH)) {
return new ChallengeError_1.ChallengeError(`Header Authorization must be type: ${MUTUAL_AUTH}`, ChallengeError_1.ChallengeStage.ClientChallenge);
}
const keyResult = KEY_REGEX.exec(authHeader);
if (!keyResult) {
return new ChallengeError_1.ChallengeError(`Header Authorization must be in the format: 'Authorization: Mutual ${keyFieldName}=[base64 key],(${challengeFieldName}|${responseFieldName})[base64 challenge],[base64 signature]'`, ChallengeError_1.ChallengeStage.ClientChallenge);
}
const challengeResult = CHALLENGE_REGEX.exec(authHeader);
if (!challengeResult) {
return new ChallengeError_1.ChallengeError(`Header Authorization must be in the format: 'Authorization: Mutual ${keyFieldName}=[base64 key],(${challengeFieldName}|${responseFieldName})[base64 challenge],[base64 signature]'`, ChallengeError_1.ChallengeStage.ClientChallenge);
}
if (challengeResult[ValueRegExIx.Challenge]) {
return {
userId: keyResult[KeyRegExIx.Value],
clientRequested: {
message: Buffer.from(challengeResult[ValueRegExIx.Message], "base64"),
signature: Buffer.from(challengeResult[ValueRegExIx.Signature], "base64"),
},
requestDateTime: new Date(),
};
}
return {
userId: keyResult[KeyRegExIx.Value],
clientResponsed: {
message: Buffer.from(challengeResult[ValueRegExIx.Message], "base64"),
signature: Buffer.from(challengeResult[ValueRegExIx.Signature], "base64"),
},
};
};
};
exports.challengeByBase64Header = challengeByBase64Header;
//# sourceMappingURL=RequestFuncs.js.map