From 3f1c93c199004b87f0819248d7778403c068ed49 Mon Sep 17 00:00:00 2001 From: Konstantin Ignatov Date: Thu, 12 Mar 2026 13:42:00 +0100 Subject: [PATCH] Update readme - add new options and BFF example --- readme.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/readme.md b/readme.md index 7675dc9..076e0a7 100644 --- a/readme.md +++ b/readme.md @@ -8,6 +8,10 @@ The authentication library allows you to easily authenticate with the Elfsquad A - `redirectUri` callback entry point of your app. - `scope` (optional) Requested authentication scope. Defaults to `Elfskot.Api offline_access`. - `loginUrl` (optional) URL of the authentication service. Defaults to `https://login.elfsquad.io`. +- `responseMode` (optional) OAuth response mode, either `'fragment'` or `'query'`. Defaults to `'fragment'`. +- `storeRefreshToken` (optional) Callback to store the refresh token server-side. When provided, the library will call this instead of saving the token to `localStorage`. Must be provided together with `refreshAccessToken` and `revokeRefreshToken`. +- `refreshAccessToken` (optional) Callback to refresh the access token via a server-side endpoint. When provided, the library will call this instead of using the built-in `localStorage`-based refresh flow. Must be provided together with `storeRefreshToken` and `revokeRefreshToken`. +- `revokeRefreshToken` (optional) Callback to revoke the server-side refresh token on sign-out. Must be provided together with `storeRefreshToken` and `refreshAccessToken`. ## Methods @@ -43,3 +47,31 @@ authenticationContext.isSignedIn().then((isSignedIn) => { } }); ``` + +### BFF pattern (secure refresh token storage) + +Use the `storeRefreshToken`, `refreshAccessToken`, and `revokeRefreshToken` callbacks to move refresh tokens out of `localStorage` into server-side HttpOnly cookies, eliminating XSS exposure of long-lived credentials. + +```js +import { AuthenticationContext } from "@elfsquad/authentication"; + +const authenticationContext = new AuthenticationContext({ + clientId: "c2a349a9-02ea-4e1e-a59d-65870529f713", + redirectUri: "https://example.com", + storeRefreshToken: (token) => + fetch("/auth/store-token", { + method: "POST", + body: JSON.stringify({ token }), + }).then(() => {}), + refreshAccessToken: () => + fetch("/auth/refresh").then((r) => r.json()), + revokeRefreshToken: () => + fetch("/auth/revoke", { method: "POST" }).then(() => {}), +}); + +authenticationContext.onSignIn().then(() => { + authenticationContext.getAccessToken().then((accessToken) => { + console.log("accessToken", accessToken); + }); +}); +```