From a83f979bb76d808df4f0a624a1e015ffc9ab827b Mon Sep 17 00:00:00 2001 From: Simon McAllister Date: Mon, 11 Mar 2024 23:40:33 +0000 Subject: [PATCH] update tests --- src/__tests__/mocks/data.ts | 45 +++++++++++-------- src/__tests__/mocks/index.ts | 1 + src/__tests__/test-cases/credentials.ts | 3 ++ .../test-cases/srp-sessions-signed.ts | 12 +++-- src/__tests__/test-cases/srp-sessions.ts | 12 +++-- .../unit/create-password-hash.test.ts | 13 +++--- src/__tests__/unit/create-secret-hash.test.ts | 13 +++--- src/__tests__/unit/create-srp-session.test.ts | 31 ++++++++----- src/__tests__/unit/sign-srp-session.test.ts | 16 +++++-- src/types.ts | 3 ++ 10 files changed, 97 insertions(+), 52 deletions(-) diff --git a/src/__tests__/mocks/data.ts b/src/__tests__/mocks/data.ts index 8603724..c3da960 100644 --- a/src/__tests__/mocks/data.ts +++ b/src/__tests__/mocks/data.ts @@ -1,27 +1,33 @@ import { AuthFlowType, ChallengeNameType } from "@aws-sdk/client-cognito-identity-provider"; -const username = "username"; -const password = "password"; -const poolId = "eu-west-2_bBpjKlyj6"; -const clientId = "EPswPGbpdBLZnh9XW134hK7qYe"; -const secretId = "ps50nb7hd1umdnmlt1xa9nwiscqvdvzy5ijw63vcacd09yihc2b"; -const secretHash = "oUkNFqfm7UjLds8vXFWarT1l3gqORGoztf+EyFmoX2Q="; -const passwordHash = "266629fd96baf8f433a4f01562eea59dd99a721dac75ae600e06bc697b2016ff"; -const poolIdAbbr = "bBpjKlyj6"; -const timestamp = "Tue Feb 1 03:04:05 UTC 2000"; -const smallA = "abcdef0123456789"; -const largeA = +export const sub = "a2c2e290-6d0f-4a08-a5ca-f0162935f3a6"; +export const username = "john.doe"; +export const email = "yorej57765@comsb.com"; +export const phone = "01234567890"; +export const password = "Qwerty1!"; +export const passwordHash = "cd9896b264dc8dca270b0b74b039cf775ea70afb06bd253f5e0ffe7197224aa3"; +export const poolId = "eu-west-2_eYpv1mFHB"; +export const clientId = "18u8119jgbpr464n28s1itk2mq"; +export const secretId = "ps50nb7hd1umdnmlt1xa9nwiscqvdvzy5ijw63vcacd09yihc2b"; +export const secretHash = "QW3YkSgjkc9VNMtbTkuQflK54A6+9GS8ZiRDj0mSvPI="; +export const poolIdAbbr = "eYpv1mFHB"; +export const timestamp = "Tue Feb 1 03:04:05 UTC 2000"; +export const smallA = "abcdef0123456789"; +export const largeA = "362be8c4c29e414549c30c6679ddbb556c27717d80c8feec68257bf5edcd855fbd23590841c1f792dd24a09243c00d4fbb8cc8047fbe1c95da7b467d29269d2db462c6268f10ef5a3c23f71865a54bae6e48523e6a7a9b65d115c66a2f5b4ec5b7384c9796dc6b2d422ea630e1821104ab05cb4a4f292f991d771be4fdba39bc6ff8dce0f0addaaaf172d908d08544d573a2222f1e198caf65f5e6445848ed23b5bbfff0b5bc00ca54b2831a200577220cfe4f5de20b66baffbfc8d3a16af6f6a7a590e0764ccdf918daf922df1ed0a695702c9bd63a69b09b4c2fb8a3bffee5f89744639607e1920ee006d81f09cba7682e75be5b407fb5cb1f706c0dbf7a9325b5c56ea53333ba1aecab647beae4b2b44c0912814609560fda8d86e6aff0b2317e339d2d3b422069d8e68fca8a39c43acb360d4285bb2dd076bb58b41e07be255f349537adaae3bf5260b2c7e066fb77904ebcee5005cc367f926482f9b405952f50e1182049ac49847a048fca4fbe13c6538eea38132c9bc43c9b05690bb7"; -const largeB = - "a2a9be7148a622a87b92513959336c923ab748fdde47e1eae8e0b4495bfc950e65a4c2cf09ac9ab38c85dbc31100bda601bb44d03d8c8a47770cdace442bea4c30ac83df807c2d2dfd6d8b449178c4c558108d141bdd79f8695d40ce25d77b1d7715a53b0022782b71105710e476b484e7c01d9625eafe4d50aff1808712d4c2636a7bb83b008fb8f398d79c5dfe59074ee0df3240253e5719c18b343f49ef5d975d89e2c481628eadca30a90ab6c41d7b9308aa6f6fc618813393ace0f52562f51f26c3fc3160e9dc99f78e9bc22758eeb7f22c137a962de99a66feb7a23e179a599813c8431c364ee193b64eef9bca04117ceba50140bafe1a0aea262c0b9bcde235866da2f1c174063d685ad67f231fcef7dca62a327f6cf2279b5fa17383acd1868629d75523e87e14cdb214ea14ce6d47228e350e4d1d451a1238886d6b3dae1d59b79321ab740c995b28c6e03a61cf76383ce1906f86389927d3575e751cfe4ab50c1eef52dd79aee69512b88f237bd74d04e8cc72d0ab94c0ad934f26"; -const salt = "8f6a1dad94d7b82c5e3031d21a251b0f"; -const secret = - "F+iU1RhIMWd3K64Qg+J/eud+WYMsW1tDULDQ4boHjzgdNFiBSKFX3BvoMHZJ2MjKv6nKMRgjifbx5sjdrBi2n+Nat+9E1QD0rzeJ2l2oOeVXruiwItacGO5AjM9PU1sFtZu4N13oNbsx9DUY7diIB+ksKz8LjxJV4FP055O1OJzEGbSY+RHAw3d3HsY2xsE9Zy6bD5FpSrONwKZWWUpZXSexPiDHzGIcRyBBYXwOKAJ+1pCtZW/Jg+MuW6hiYfTMEGk8vr/35TmiAHjYRe1urxElaa+fJi41j1tpX5FhrHfNp3WmuVj6cWJwkhZ/GKGL000lwsXDEY83C2v2czpjP1VwyDf2UPxI1BNPMVjCWZx5V/9D5SniPUWCNpwyh+ZSCVvRJxQitMcV0klswY36itXXn7OCurUjgqViUIBPbrVDcbuZ49tR4UoHlQXNzsmzXwlGwyHvNUHjNAT/6/qAAtmHwJbT6GZzceN1g+33P0Eq2BIWxj16pnhPKykrGuvIV3TpcL9FY0CcTKqozRfC2pOWenT08md++uq39z9OP+wA/7Fjt1ceLOiDcRhEW0xhoBqu/3V7RDNDUqV2bLH7rEq7Q5PCGhsRu8h9crUbVtNOUrna/o7HmRy0XiBQdjLP7Xe6uASNZAAso4eUZce0oc2LIpHvAx6BK8cw8rp2Pcg+ZnC0HgcpBEF6sHJEcH4GmZNJ10c/exITniVKSJkP1C8iPqulNug6OMmSav3WpMvj/qb/t8JPNqbePj99fANkteG7JPUY9LoE/wsBDIeYEA4lZ4HvKZw9g8RbltYNmOQAa6K4XXI0AEspx1+TT5A+cJl48BPk+f46SCThCzK/8N9XHaerojUqu4EWW1l5c+WRaOCdvo/HQidTn1VQJ6lcyJwcuyoxy7MlESMfs1G9rgehHbYjWNxoUwX/AwFfNzS/7dMENhDFx+ZUsT0wgrn+iMhfJJPHG4lt0N/R6JjQ8IOgaUZ7CZdrL7pQxA5v0eqWwZ/cYJVAI+mGLez1ldYQRvZkw0dOkpCjCDrw7ZTKnsyRLDE6KyyNT+ykJq7aGyAHb5nxualN0B8OnqY1hh+tZ5xTOh9jlnvBo7dwfsbZpjsGGLiMLbc411cT+FUONrlPdK9wDEZdQ8jcys4PfeCzcju/VnNEbbv1EuxG5bIWGApSOVf04p2/0bBWn8VJkKoCsC9+QhV2KwTRfCLZWloYIc/N1QuzXf328m9FG3vihrXvkgcxxsSbUjMb4QhR7DkYIN6kWsguBOVTybdTi4vlNqFzX8bJtK3uQNKC98yYzZjR40HFOydBJjLckUandwu1blgqM3IwlmYWMiPcFx2SGQRIufq8hLOhyE12ulT9KI4c2D+yLn7hASICW/3z7LgfuWq6j1FDVlmSqM00C8wZ84DzT056HLETpWpl1Gh3QRJPkReqRKlY0Bqrk5koMfmRuGht/WnyXxs0gSAkWFOevpvYopyHBhMTdc7DlGE70QcRJiBeuJkKNOoih+lOkHGFof5xnFWzaZkuouBZFntSn4xZxEAb1Tl56k1b8oCIHLvrsnlqxMHfNYlnQUO+gnhFgDc6AlyQCtc6+wlulggchkPFMgjlaN/w6h3N9697ksRnySNMNAkCx+VgP+qbgn24pGYWWtlCWWpsdkxU6OzpFQwBchqBw9LUB5MyqjwWLssMxlJxg0KgXnRNfwv5jd0sAE5KvT4vFCt0FA=="; -const passwordSignature = "AmaS40dQC4mBIgVaKNkAvWpYBmHUi/gv/XKVVCr8xyE="; +export const largeB = + "bc071b539bfaa44b26a4f4a917dcc4b90291f3fea737baa555c0dfc792f11849902859dd52976fd7367130d91969670e8a0beb66d044641709d7a9ea609e2cc5baac6837e1ee8f8d9ccdce535be1dee59d4c893d9c9a1f06ddacb9d927e29c0e8bb1b8dda315f297e82c6095570ae3ab28a9110dfc4367296d77898b1d69d029f76e16ffebed59fc568548a9fb54a1a462440b19b4e4d89ae414374654788d599d0635f9b8a7a5c6a8556e675c4e01690d5324eecd092d269b2be31fa2dc7192cb0bec8a390ca4ce791c8e8cc9ed7258929430a2802a2b9dadd985a004d584e883621ff3518e223a6dbab5071bc844e4ee7d12f6c29bd9197f0fefcee91020b0903596cf170efd27648eb5de5ab2961032cf759dbc48dadb6db0dd585bb9c1e9f73bbea67a7ca406e26d4333c63d5339fa8c0f51fc12df554737da39fc780c0a648e884600f1bf9398cedddaee7d6db6ace4e0007d97f7322d7270dc25c6e6ae000e54b62f8cb868b16e16eadb4c8c87f3baae1c1b8e59aabb73771e62c0b898"; +export const salt = "baf4431cdaa37c04c0d655a99f5e9b9b"; +export const secret = + "gn7F/ENIPPk/KZ7P2xYr4S0pZhCn29Y0nxXBtEPEc8Tt2cqbQpWorIuwSAC0g3fpDW9djD5+b9v30TctMTiVt6xjGaZeuWzzgAnVrc0l0xROzJItEQM1V96ySkrfFbL4tKuZokrqiszsRkgwnu4SGBz3akVpUD8pZnAg1Ycfc3LLSyQETFTndRHjS8UFGIovw7wqQfxKNKDC1nY2XYWR1nFuEIvHXb+Tvc76IxNZcaEvl5sAuTjwpVlmfwPSOELXnYxvDxUcFYO3sNguNqahn6aH4j16ccEZ/Wqoubn7QkomXV3Qdo5khQbw4F9CWFaxCHoRZwFAc8RQ4oGiIHLvuMb/Y/JhGTL3HefSkBXQ+uvoPK7YdgY8yn3SejYv4xD8lw+KLTPy1EbCXX9Aq1uwgjzeSygLl7/tkf1C/YzhefXEOfaLk2eNRlAschYunQ7WeIZWBYzW+38+r4bQpaecj8GcH/ycAOpacfoLB+/q3E/dHsFOFlzetYO6Qll5AXEv4hzJZgNh1/2zK3N8j2JBUjZs2h60Rh8OS+ZcQGa7ICPfS7XDvSV8U6Xan3j2m0Azz2ara+1I4MYDVj5P4/BneVDh4L+6Dl3EWEAF9UO8Ur1/5seiOVcAQe3TlwN9UWgmOZHIq/UGU14ofpmZI46WWS3qB+yBPHbWWJ0MMFFtRwCTzFl+2kRGthRR5A+6MSuLCfdcQwqb6FYRZEdgXZzMa6Td0Pog/5TFqxygkRB0P3Yq4lfOnRKI6cC3+2g8uMsEmOJfzsVrsfi6GTAPrP+lIPpNe12ZquFzPGi9Z68Odj+aNDYChalBpuvJgxWR2EFuyj2MebKz6Zo/5V/w964aTTYjUt1pPHURLx3MKl7Ns1xF1lklQ1DAOQYNrVWxWJRs4TxipduEq4N02uh9XKWzXxLJuHsc1B9e1Dc+1sHs122POq7i/VYoln6LhO30o32lDHOGa56krde0N/+FY7034zB1pqL8VuDd2/8o8XZ+D/ez/1gBwQ2y1q6CRvvZmNyYBIC8an/Vgb++e5zgx6Cb43o9+PEFc8UEA8QljTgZ2m+kwjia1TSYeyYnKQOIqCKMkZa6IBIwMZ6AHIDSWk//IR/UMiq4QGfb5CJFPYOTKSGXEU9dFPYbx+pZmq/Fq7QgFCM/I7M6jKZPwn+T4/RGLEg1YNRwQS/oQI/uu5iF9sIbtWO5XTRQ8q2ld4s3tEFflYdmELHXrt1UuFaCi82iTJZAgFPeIx9mHPb0U+I7iutfEPogIE5b/2T+qJhIBgeIQUVsJuo+uLdriFm1c7YwBMBTJWC9R2mL+2x6quavpx7u0zgHrmbDxFx6+nBl0DEZxsY5h8AEDUVhyi2w+7aK9T/uh7Pz3/fH+AwXfWcA1cBueYYHX0Due6+3hRAHfOokXTbi27+YoS2AKuXDl2EibHedm5lb1Tg18V66dXtGsvpIn/OUWO2FphUGdtCMgZc51ahYTiN1m6Qqx+z1DFRM2BLw6HLxb1uT1OmDyucvCXIsMl4vNyyeIdJwstIbQrECxg1Fdow6jHrzKyJw/FKsYGSnyDRk++1jTt3J46wz16S45XaMSDG8RMH7AKKeAX/lfJ0d247ajB4U8Hei1h1kclX/DAYp7A0KyoCG7Qt9hZGsxhsloT2eYohHEKshPDs2WU48WtuHwgXydkTABvx3b1ixLp2CEuQiMyy3jZpvDD8WGaqWqbQgnH/yQw=="; +export const passwordSignature = "RrSiIBQazZkaxHQf34oRro1qjzfEvwdP6/Avltpd34E="; // This object isn't typed because it is a collection of external inputs export const mockCredentials = { + sub, username, + email, + phone, password, poolId, clientId, @@ -33,7 +39,9 @@ export const mockCredentials = { export const mockSession = { username, - passwordHash, + password: passwordHash, + isHashed: true, + poolId, poolIdAbbr, timestamp, smallA, @@ -72,6 +80,7 @@ export const mockInitiateAuthResponse = { SRP_B: largeB, SALT: salt, SECRET_BLOCK: secret, + USER_ID_FOR_SRP: sub, }, }; diff --git a/src/__tests__/mocks/index.ts b/src/__tests__/mocks/index.ts index c159d9f..402e901 100644 --- a/src/__tests__/mocks/index.ts +++ b/src/__tests__/mocks/index.ts @@ -1 +1,2 @@ +export * as data from "./data"; export * as factories from "./factories"; diff --git a/src/__tests__/test-cases/credentials.ts b/src/__tests__/test-cases/credentials.ts index 1bf1d51..8b70b1e 100644 --- a/src/__tests__/test-cases/credentials.ts +++ b/src/__tests__/test-cases/credentials.ts @@ -18,6 +18,9 @@ export const positiveCredentials: Record = { allowSpecialCharacters: true, }), }), + usernamePhone: mockCredentialsFactory({ + username: faker.phone.number(), + }), usernameUuid: mockCredentialsFactory({ username: faker.datatype.uuid(), }), diff --git a/src/__tests__/test-cases/srp-sessions-signed.ts b/src/__tests__/test-cases/srp-sessions-signed.ts index 7af71be..87786d5 100644 --- a/src/__tests__/test-cases/srp-sessions-signed.ts +++ b/src/__tests__/test-cases/srp-sessions-signed.ts @@ -18,6 +18,9 @@ export const positiveSrpSessionsSigned: Record = { allowSpecialCharacters: true, }), }), + usernamePhone: mockSrpSessionSignedFactory({ + username: faker.phone.number(), + }), usernameUuid: mockSrpSessionSignedFactory({ username: faker.datatype.uuid(), }), @@ -27,12 +30,15 @@ export const positiveSrpSessionsSigned: Record = { usernameEmpty: mockSrpSessionSignedFactory({ username: "", }), - // passwordHash + // password + passwordPlain: mockSrpSessionSignedFactory({ + password: faker.internet.password(), + }), passwordHashRandom: mockSrpSessionSignedFactory({ - passwordHash: faker.random.alphaNumeric(64, { casing: "lower" }), + password: faker.random.alphaNumeric(64, { casing: "lower" }), }), passwordHashEmpty: mockSrpSessionSignedFactory({ - passwordHash: "", + password: "", }), // poolIdAbbr poolIdAbbrRandom: mockSrpSessionSignedFactory({ diff --git a/src/__tests__/test-cases/srp-sessions.ts b/src/__tests__/test-cases/srp-sessions.ts index 17df4e9..948fec7 100644 --- a/src/__tests__/test-cases/srp-sessions.ts +++ b/src/__tests__/test-cases/srp-sessions.ts @@ -17,6 +17,9 @@ export const positiveSrpSessions: Record = { allowSpecialCharacters: true, }), }), + usernamePhone: mockSrpSessionFactory({ + username: faker.phone.number(), + }), usernameUuid: mockSrpSessionFactory({ username: faker.datatype.uuid(), }), @@ -26,12 +29,15 @@ export const positiveSrpSessions: Record = { usernameEmpty: mockSrpSessionFactory({ username: "", }), - // passwordHash + // password + passwordPlain: mockSrpSessionFactory({ + password: faker.internet.password(), + }), passwordHashRandom: mockSrpSessionFactory({ - passwordHash: faker.random.alphaNumeric(64, { casing: "lower" }), + password: faker.random.alphaNumeric(64, { casing: "lower" }), }), passwordHashEmpty: mockSrpSessionFactory({ - passwordHash: "", + password: "", }), // poolIdAbbr poolIdAbbrRandom: mockSrpSessionFactory({ diff --git a/src/__tests__/unit/create-password-hash.test.ts b/src/__tests__/unit/create-password-hash.test.ts index 785c214..e0c4ca6 100644 --- a/src/__tests__/unit/create-password-hash.test.ts +++ b/src/__tests__/unit/create-password-hash.test.ts @@ -5,18 +5,17 @@ import { positiveCredentials } from "../test-cases"; describe("createPasswordHash", () => { describe("positive", () => { it("should create the correct password hash", () => { - const credentials = mockCredentialsFactory(); - const { username, password, poolId, passwordHash: expected } = credentials; - const passwordHash = createPasswordHash(username, password, poolId); - expect(passwordHash).toEqual(expected); + const { sub, password, poolId, passwordHash: expected } = mockCredentialsFactory(); + const hash = createPasswordHash(sub, password, poolId); + expect(hash).toEqual(expected); }); it.each(Object.values(positiveCredentials))( "should create a password hash with the correct format: credentials %#", (credentials) => { - const { username, password, poolId } = credentials; - const passwordHash = createPasswordHash(username, password, poolId); - expect(passwordHash).toMatch(/^[a-z0-9]{64}$/); + const { sub, password, poolId } = credentials; + const hash = createPasswordHash(sub, password, poolId); + expect(hash).toMatch(/^[a-z0-9]{64}$/); }, ); }); diff --git a/src/__tests__/unit/create-secret-hash.test.ts b/src/__tests__/unit/create-secret-hash.test.ts index 4544d70..81ae6f1 100644 --- a/src/__tests__/unit/create-secret-hash.test.ts +++ b/src/__tests__/unit/create-secret-hash.test.ts @@ -5,18 +5,17 @@ import { positiveCredentials } from "../test-cases"; describe("createSecretHash", () => { describe("positive", () => { it("should create the correct secret hash", () => { - const credentials = mockCredentialsFactory(); - const { username, clientId, secretId, secretHash: expected } = credentials; - const secretHash = createSecretHash(username, clientId, secretId); - expect(secretHash).toEqual(expected); + const { sub, clientId, secretId, secretHash: expected } = mockCredentialsFactory(); + const hash = createSecretHash(sub, clientId, secretId); + expect(hash).toEqual(expected); }); it.each(Object.values(positiveCredentials))( "should create a secret hash with the correct format: credentials %#", (credentials) => { - const { username, clientId, secretId } = credentials; - const secretHash = createSecretHash(username, clientId, secretId); - expect(secretHash).toMatch(/^[a-zA-Z0-9+=/]+$/); + const { sub, clientId, secretId } = credentials; + const hash = createSecretHash(sub, clientId, secretId); + expect(hash).toMatch(/^[a-zA-Z0-9+=/]+$/); }, ); }); diff --git a/src/__tests__/unit/create-srp-session.test.ts b/src/__tests__/unit/create-srp-session.test.ts index 0d2624d..3dc2642 100644 --- a/src/__tests__/unit/create-srp-session.test.ts +++ b/src/__tests__/unit/create-srp-session.test.ts @@ -9,15 +9,14 @@ import { positiveCredentials, positiveTimestamps } from "../test-cases"; describe("createSrpSession", () => { describe("positive", () => { - it("should create the correct SRP session", () => { + it("should create the correct SRP session for a hashed password", () => { // ensure randomBytes returns what we expect const { smallA } = mockSrpSessionFactory(); jest.spyOn(utils, "randomBytes").mockReturnValueOnce(Buffer.from(smallA, "hex")); // Tue Feb 1 03:04:05 UTC 2000 in Unix timestamp jest.useFakeTimers().setSystemTime(new Date(949374245000)); - const credentials = mockCredentialsFactory(); - const { username, passwordHash, poolId } = credentials; + const { username, passwordHash, poolId } = mockCredentialsFactory(); const session = createSrpSession(username, passwordHash, poolId); const expected = mockSrpSessionFactory(); expect(session).toEqual(expected); @@ -25,6 +24,21 @@ describe("createSrpSession", () => { jest.useRealTimers(); }); + it("should create the correct SRP session for a unhashed password", () => { + // ensure randomBytes returns what we expect + const { smallA } = mockSrpSessionFactory(); + jest.spyOn(utils, "randomBytes").mockReturnValueOnce(Buffer.from(smallA, "hex")); + // Tue Feb 1 03:04:05 UTC 2000 in Unix timestamp + jest.useFakeTimers().setSystemTime(new Date(949374245000)); + + const { username, password, poolId } = mockCredentialsFactory({ password: "Qwerty1!" }); + const session = createSrpSession(username, password, poolId, false); + const expected = mockSrpSessionFactory({ password, isHashed: false }); + expect(session).toEqual(expected); + + jest.useRealTimers(); + }); + it.each(Object.values(positiveCredentials))( "should create a SRP session with the correct format: credentials %#", (credentials) => { @@ -32,7 +46,7 @@ describe("createSrpSession", () => { const session = createSrpSession(username, passwordHash, poolId); expect(session.username).toMatch(username); - expect(session.passwordHash).toMatch(passwordHash); + expect(session.password).toMatch(passwordHash); expect(session.poolIdAbbr).toMatch(poolId.split("_")[1]); expect(session.timestamp).toMatch( /(Sun|Mon|Tue|Wed|Thu|Fri|Sat){1} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec){1} [1-3]?[0-9] (2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9]) UTC [0-9]{1,4}/, @@ -46,8 +60,7 @@ describe("createSrpSession", () => { "should create a timestamp with the correct format: epoch %#", (epoch) => { jest.useFakeTimers().setSystemTime(new Date(epoch)); - const credentials = mockCredentialsFactory(); - const { username, passwordHash, poolId } = credentials; + const { username, passwordHash, poolId } = mockCredentialsFactory(); const { timestamp } = createSrpSession(username, passwordHash, poolId); expect(timestamp).toMatch( /(Sun|Mon|Tue|Wed|Thu|Fri|Sat){1} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec){1} [1-3]?[0-9] (2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9]) UTC [0-9]{1,4}/, @@ -57,8 +70,7 @@ describe("createSrpSession", () => { ); it("should not create the same SRP session on successive calls", () => { - const credentials = mockCredentialsFactory(); - const { username, passwordHash, poolId } = credentials; + const { username, passwordHash, poolId } = mockCredentialsFactory(); const sessionA = createSrpSession(username, passwordHash, poolId); const sessionB = createSrpSession(username, passwordHash, poolId); expect(sessionA).not.toEqual(sessionB); @@ -67,8 +79,7 @@ describe("createSrpSession", () => { describe("negative", () => { it("should throw a AbortOnZeroASrpError if SRP A is 0", () => { - const credentials = mockCredentialsFactory(); - const { username, passwordHash, poolId } = credentials; + const { username, passwordHash, poolId } = mockCredentialsFactory(); // make sure our A = G % a ^ N calculation returns 0 diff --git a/src/__tests__/unit/sign-srp-session.test.ts b/src/__tests__/unit/sign-srp-session.test.ts index ce30911..fd30d5d 100644 --- a/src/__tests__/unit/sign-srp-session.test.ts +++ b/src/__tests__/unit/sign-srp-session.test.ts @@ -18,14 +18,14 @@ import { import { negativeInitiateAuthResponses as negativeResponses, positiveInitiateAuthResponses as positiveResponses, - positiveSrpSessions as positiveSessions, + positiveSrpSessionsSigned as positiveSessions, } from "../test-cases"; const { ChallengeParameters } = mockInitiateAuthResponseFactory(); describe("signSrpSession", () => { describe("positive", () => { - it("should create the correct signed SRP session", () => { + it("should create the correct signed SRP session for a hashed password", () => { const session = mockSrpSessionFactory(); const response = mockInitiateAuthResponseFactory(); const sessionSigned = signSrpSession(session, response); @@ -33,6 +33,14 @@ describe("signSrpSession", () => { expect(sessionSigned).toEqual(expected); }); + it("should create the correct signed SRP session for a unhashed password", () => { + const session = mockSrpSessionFactory({ password: "Qwerty1!", isHashed: false }); + const response = mockInitiateAuthResponseFactory(); + const sessionSigned = signSrpSession(session, response); + const expected = mockSrpSessionSignedFactory({ password: "Qwerty1!", isHashed: false }); + expect(sessionSigned).toEqual(expected); + }); + it.each(Object.values(positiveSessions))( "should create a signed SRP session with the correct format: session %#", (session) => { @@ -41,7 +49,7 @@ describe("signSrpSession", () => { const { SRP_B, SALT, SECRET_BLOCK } = response.ChallengeParameters ?? {}; // previous session values should remain the same expect(sessionSigned.username).toMatch(session.username); - expect(sessionSigned.passwordHash).toMatch(session.passwordHash); + expect(sessionSigned.password).toMatch(session.password); expect(sessionSigned.poolIdAbbr).toMatch(session.poolIdAbbr); expect(sessionSigned.timestamp).toMatch(session.timestamp); expect(sessionSigned.smallA).toMatch(session.smallA); @@ -63,7 +71,7 @@ describe("signSrpSession", () => { const { SRP_B, SALT, SECRET_BLOCK } = response.ChallengeParameters ?? {}; // previous session values should remain the same expect(sessionSigned.username).toMatch(session.username); - expect(sessionSigned.passwordHash).toMatch(session.passwordHash); + expect(sessionSigned.password).toMatch(session.password); expect(sessionSigned.poolIdAbbr).toMatch(session.poolIdAbbr); expect(sessionSigned.timestamp).toMatch(session.timestamp); expect(sessionSigned.smallA).toMatch(session.smallA); diff --git a/src/types.ts b/src/types.ts index 92feec7..a0ecea6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -154,7 +154,10 @@ export type RespondToAuthChallengeRequest = * Credentials needed for SRP authentication. */ export type Credentials = { + sub: string; username: string; + email: string; + phone: string; password: string; poolId: string; clientId: string;