diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8a78cfc..e0088dd60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to the Aptos TypeScript SDK will be captured in this file. This changelog is written by hand for now. It adheres to the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Unreleased +- Add support for Firebase issuers in the `updateFederatedKeylessJwkSetTransaction` function # 1.32.0 (2024-11-08) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d4258839..dcae276de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -141,6 +141,7 @@ these commands. ```bash git checkout "bump_version" // update version in `package.json` +// update CHANGELOG.md pnpm update-version ``` diff --git a/src/internal/keyless.ts b/src/internal/keyless.ts index 5485fc762..d02545dbc 100644 --- a/src/internal/keyless.ts +++ b/src/internal/keyless.ts @@ -31,6 +31,7 @@ import { MoveVector } from "../bcs"; import { generateTransaction } from "./transactionSubmission"; import { InputGenerateTransactionOptions, SimpleTransaction } from "../transactions"; import { KeylessError, KeylessErrorType } from "../errors"; +import { FIREBASE_AUTH_ISS_PATTERN } from "../utils/const"; /** * Retrieves a pepper value based on the provided configuration and authentication details. @@ -232,7 +233,16 @@ export async function updateFederatedKeylessJwkSetTransaction(args: { options?: InputGenerateTransactionOptions; }): Promise { const { aptosConfig, sender, iss, options } = args; - const jwksUrl = args.jwksUrl ?? (iss.endsWith("/") ? `${iss}.well-known/jwks.json` : `${iss}/.well-known/jwks.json`); + + let { jwksUrl } = args; + + if (jwksUrl === undefined) { + if (FIREBASE_AUTH_ISS_PATTERN.test(iss)) { + jwksUrl = "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com"; + } else { + jwksUrl = iss.endsWith("/") ? `${iss}.well-known/jwks.json` : `${iss}/.well-known/jwks.json`; + } + } let response: Response; diff --git a/src/utils/const.ts b/src/utils/const.ts index 05ae5c2a6..d1641d695 100644 --- a/src/utils/const.ts +++ b/src/utils/const.ts @@ -65,3 +65,10 @@ export enum ProcessorType { USER_TRANSACTION_PROCESSOR = "user_transaction_processor", OBJECT_PROCESSOR = "objects_processor", } + +/** + * Regular expression pattern for Firebase Auth issuer URLs + * Matches URLs in the format: https://securetoken.google.com/[project-id] + * where project-id can contain letters, numbers, hyphens, and underscores + */ +export const FIREBASE_AUTH_ISS_PATTERN = /^https:\/\/securetoken\.google\.com\/[a-zA-Z0-9-_]+$/; diff --git a/tests/e2e/api/keyless.test.ts b/tests/e2e/api/keyless.test.ts index 723f8017e..f7e06d903 100644 --- a/tests/e2e/api/keyless.test.ts +++ b/tests/e2e/api/keyless.test.ts @@ -101,6 +101,24 @@ describe("keyless api", () => { KEYLESS_TEST_TIMEOUT, ); + test( + "installs jwks for a firebase iss", + async () => { + const sender = Account.generate(); + await aptos.fundAccount({ + accountAddress: sender.accountAddress, + amount: FUND_AMOUNT, + }); + const jwkTransaction = await aptos.updateFederatedKeylessJwkSetTransaction({ + sender, + iss: "https://securetoken.google.com/aptos-build", + }); + const committedJwkTxn = await aptos.signAndSubmitTransaction({ signer: sender, transaction: jwkTransaction }); + await aptos.waitForTransaction({ transactionHash: committedJwkTxn.hash }); + }, + KEYLESS_TEST_TIMEOUT, + ); + test("submitting a keyless txn using an outdated JWK should error with meaningful message", async () => { const jwt = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InRlc3QtcnNhMiJ9.eyJpc3MiOiJ0ZXN0Lm9pZGMucHJvdmlkZXIiLCJhdWQiOiJ0ZXN0LWtleWxlc3MtZGFwcCIsInN1YiI6InRlc3QtdXNlciIsImVtYWlsIjoidGVzdEBhcHRvc2xhYnMuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlhdCI6OTg3NjU0MzIwOSwiZXhwIjo5ODc2NTQzMjEwLCJub25jZSI6IjcwOTUyNDIzMzM5NjQ0NTcyNjc5MzQ3MjM3NjgwODAzMDMzMjQ0NjI4MjExOTE3NTY0MDk0NTAwOTk1MTk3ODEwNTE5MTAxODcxMTgifQ.RmAz3eE_aVxjMGFHttKkUzPvwvDQuVdGFgXV3VihhY7a2B8juk_Pw-NqLEEgLDsB_Vh1jDoPySvogiEDwHZ5fToqk9brImdfmACw27pr--MQ6kn6n0k2XOPmMqjQ7KEMM43Rf7sK_9T-guovf0IVR44sJDqnCJanXBdZK52jNRvj2zmkMypVYXQHAz5jvJlCQcnTh0MpIm9IOgRzjKTk0ax8Wr9IDzzw__ljj036climWBzhGKKw9aKIek70Ug6h2604oI8CBRlxOKimw24NXIO_2jQBRMfeTW_hIm9q3pQ1OML-f7PMGdAAyVGx_sEM0wwYpcDfjBEgK1_RgRANRg";