cognito-srp
Version:
Secure Remote Password protocol implementation compatible with Amazon Cognito.
90 lines (89 loc) • 4.61 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const AwsEndpoint_1 = require("./AwsEndpoint");
const UserPool_1 = require("./UserPool");
const util_1 = require("./util");
const Session_1 = require("./Session");
var CognitoActions;
(function (CognitoActions) {
CognitoActions["InitiateAuth"] = "InitiateAuth";
CognitoActions["RespondToAuthChallenge"] = "RespondToAuthChallenge";
})(CognitoActions = exports.CognitoActions || (exports.CognitoActions = {}));
function createCognitoEndpoint(userPoolId, userList) {
return __awaiter(this, void 0, void 0, function* () {
const [, poolname] = userPoolId.split('_');
const userPool = new UserPool_1.UserPool(poolname);
const users = yield Promise.all(userList.map(user => userPool.createUser(user)));
return new AwsEndpoint_1.AwsEndpoint('AWSCognitoIdentityProviderService', {
InitiateAuth(request, response) {
return __awaiter(this, void 0, void 0, function* () {
const params = request.body.AuthParameters;
const username = params.USERNAME;
const user = users.find(user => user.username === username);
if (user) {
const challenge = yield userPool.getServerChallenge(user);
const srpB = challenge.calculateB().toString('hex');
const hkdf = challenge.getSession(params.SRP_A).getHkdf();
response.json({
ChallengeName: 'PASSWORD_VERIFIER',
ChallengeParameters: {
SALT: user.salt,
SECRET_BLOCK: hkdf,
SRP_B: srpB,
USERNAME: username,
USER_ID_FOR_SRP: username
}
});
}
else {
response.json({
ChallengeName: 'PASSWORD_VERIFIER',
ChallengeParameters: {
SALT: (yield util_1.randomBytes(16)).toString('hex'),
SECRET_BLOCK: (yield util_1.randomBytes(16)).toString('hex'),
SRP_B: (yield util_1.randomBytes(384)).toString('hex'),
USERNAME: username,
USER_ID_FOR_SRP: username
}
});
}
});
},
RespondToAuthChallenge(request, response) {
return __awaiter(this, void 0, void 0, function* () {
const responses = request.body.ChallengeResponses;
const hkdf = responses.PASSWORD_CLAIM_SECRET_BLOCK;
const session = new Session_1.Session(poolname, responses.USERNAME, hkdf);
const signature = session.calculateSignature(hkdf, responses.TIMESTAMP);
if (responses.PASSWORD_CLAIM_SIGNATURE === signature) {
response.json({
AuthenticationResult: {
AccessToken: '',
ExpiresIn: 3600,
IdToken: '',
RefreshToken: '',
TokenType: 'Bearer'
},
ChallengeParameters: {}
});
}
else {
response.status(400).json({
__type: 'UserNotFoundException',
message: 'User does not exist.'
});
}
});
}
});
});
}
exports.createCognitoEndpoint = createCognitoEndpoint;