@farmsdotmarket/openauth 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @farmsdotmarket/openauth might be problematic. Click here for more details.
- package/.changeset/README.md +8 -0
- package/.changeset/commit.cjs +4 -0
- package/.changeset/config.json +11 -0
- package/.changeset/farms-openauth-release-0-4-3-farms-2.md +10 -0
- package/.changeset/popular-geese-reply.md +5 -0
- package/.changeset/stupid-boats-play.md +5 -0
- package/.changeset/ten-pans-invent.md +5 -0
- package/.github/CODE_OF_CONDUCT +15 -0
- package/.github/workflows/docs.yml +39 -0
- package/.github/workflows/format.yml +26 -0
- package/.github/workflows/release.yml +28 -0
- package/.github/workflows/test.yml +20 -0
- package/.prettierrc +3 -0
- package/CNAME +1 -0
- package/FARMS_RELEASE.md +82 -0
- package/LICENSE +22 -0
- package/PATCHES.md +32 -0
- package/README.md +311 -0
- package/bun.lockb +0 -0
- package/bunfig.toml +2 -0
- package/examples/README.md +28 -0
- package/examples/client/astro/.vscode/extensions.json +4 -0
- package/examples/client/astro/.vscode/launch.json +11 -0
- package/examples/client/astro/README.md +7 -0
- package/examples/client/astro/astro.config.mjs +10 -0
- package/examples/client/astro/package.json +15 -0
- package/examples/client/astro/public/favicon.svg +9 -0
- package/examples/client/astro/src/assets/astro.svg +1 -0
- package/examples/client/astro/src/assets/background.svg +1 -0
- package/examples/client/astro/src/auth.ts +23 -0
- package/examples/client/astro/src/components/Welcome.astro +209 -0
- package/examples/client/astro/src/env.d.ts +10 -0
- package/examples/client/astro/src/layouts/Layout.astro +22 -0
- package/examples/client/astro/src/middleware.ts +31 -0
- package/examples/client/astro/src/pages/callback.ts +19 -0
- package/examples/client/astro/src/pages/index.astro +11 -0
- package/examples/client/astro/tsconfig.json +5 -0
- package/examples/client/cloudflare-api/api.ts +80 -0
- package/examples/client/cloudflare-api/package.json +5 -0
- package/examples/client/jwt-api/CHANGELOG.md +8 -0
- package/examples/client/jwt-api/README.md +13 -0
- package/examples/client/jwt-api/index.ts +45 -0
- package/examples/client/jwt-api/package.json +15 -0
- package/examples/client/lambda-api/api.ts +69 -0
- package/examples/client/lambda-api/package.json +5 -0
- package/examples/client/nextjs/CHANGELOG.md +46 -0
- package/examples/client/nextjs/README.md +26 -0
- package/examples/client/nextjs/app/actions.ts +61 -0
- package/examples/client/nextjs/app/api/callback/route.ts +11 -0
- package/examples/client/nextjs/app/auth.ts +29 -0
- package/examples/client/nextjs/app/favicon.ico +0 -0
- package/examples/client/nextjs/app/globals.css +42 -0
- package/examples/client/nextjs/app/layout.tsx +32 -0
- package/examples/client/nextjs/app/page.module.css +169 -0
- package/examples/client/nextjs/app/page.tsx +97 -0
- package/examples/client/nextjs/next.config.ts +7 -0
- package/examples/client/nextjs/package.json +23 -0
- package/examples/client/nextjs/public/file.svg +1 -0
- package/examples/client/nextjs/public/globe.svg +1 -0
- package/examples/client/nextjs/public/next.svg +1 -0
- package/examples/client/nextjs/public/vercel.svg +1 -0
- package/examples/client/nextjs/public/window.svg +1 -0
- package/examples/client/nextjs/tsconfig.json +27 -0
- package/examples/client/react/README.md +29 -0
- package/examples/client/react/index.html +13 -0
- package/examples/client/react/package.json +30 -0
- package/examples/client/react/public/vite.svg +1 -0
- package/examples/client/react/src/App.tsx +39 -0
- package/examples/client/react/src/AuthContext.tsx +153 -0
- package/examples/client/react/src/assets/react.svg +1 -0
- package/examples/client/react/src/main.tsx +12 -0
- package/examples/client/react/src/vite-env.d.ts +1 -0
- package/examples/client/react/tsconfig.app.json +26 -0
- package/examples/client/react/tsconfig.json +11 -0
- package/examples/client/react/tsconfig.node.json +24 -0
- package/examples/client/react/vite.config.ts +7 -0
- package/examples/client/sveltekit/package.json +24 -0
- package/examples/client/sveltekit/src/app.d.ts +15 -0
- package/examples/client/sveltekit/src/app.html +12 -0
- package/examples/client/sveltekit/src/hooks.server.ts +29 -0
- package/examples/client/sveltekit/src/lib/auth.server.ts +29 -0
- package/examples/client/sveltekit/src/routes/+page.server.ts +5 -0
- package/examples/client/sveltekit/src/routes/+page.svelte +5 -0
- package/examples/client/sveltekit/src/routes/callback/+server.ts +17 -0
- package/examples/client/sveltekit/static/favicon.png +0 -0
- package/examples/client/sveltekit/svelte.config.js +18 -0
- package/examples/client/sveltekit/tsconfig.json +19 -0
- package/examples/client/sveltekit/vite.config.ts +6 -0
- package/examples/issuer/bun/issuer.ts +43 -0
- package/examples/issuer/bun/package.json +7 -0
- package/examples/issuer/cloudflare/issuer.ts +47 -0
- package/examples/issuer/cloudflare/package.json +8 -0
- package/examples/issuer/cloudflare/sst-env.d.ts +17 -0
- package/examples/issuer/cloudflare/sst.config.ts +23 -0
- package/examples/issuer/custom-frontend/auth/issuer.ts +43 -0
- package/examples/issuer/custom-frontend/auth/package.json +7 -0
- package/examples/issuer/custom-frontend/frontend/frontend.tsx +57 -0
- package/examples/issuer/custom-frontend/frontend/package.json +6 -0
- package/examples/issuer/custom-frontend/package.json +5 -0
- package/examples/issuer/lambda/issuer.ts +35 -0
- package/examples/issuer/lambda/package.json +8 -0
- package/examples/issuer/lambda/sst-env.d.ts +9 -0
- package/examples/issuer/lambda/sst.config.ts +15 -0
- package/examples/issuer/node/authorizer.ts +38 -0
- package/examples/issuer/node/package.json +5 -0
- package/examples/quickstart/sst/README.md +36 -0
- package/examples/quickstart/sst/app/actions.ts +62 -0
- package/examples/quickstart/sst/app/api/callback/route.ts +15 -0
- package/examples/quickstart/sst/app/auth.ts +29 -0
- package/examples/quickstart/sst/app/favicon.ico +0 -0
- package/examples/quickstart/sst/app/globals.css +42 -0
- package/examples/quickstart/sst/app/layout.tsx +32 -0
- package/examples/quickstart/sst/app/page.module.css +200 -0
- package/examples/quickstart/sst/app/page.tsx +53 -0
- package/examples/quickstart/sst/auth/index.ts +37 -0
- package/examples/quickstart/sst/auth/subjects.ts +8 -0
- package/examples/quickstart/sst/next.config.ts +7 -0
- package/examples/quickstart/sst/package-lock.json +1165 -0
- package/examples/quickstart/sst/package.json +26 -0
- package/examples/quickstart/sst/public/file.svg +1 -0
- package/examples/quickstart/sst/public/globe.svg +1 -0
- package/examples/quickstart/sst/public/next.svg +1 -0
- package/examples/quickstart/sst/public/vercel.svg +1 -0
- package/examples/quickstart/sst/public/window.svg +1 -0
- package/examples/quickstart/sst/sst-env.d.ts +18 -0
- package/examples/quickstart/sst/sst.config.ts +21 -0
- package/examples/quickstart/sst/tsconfig.json +27 -0
- package/examples/quickstart/standalone/README.md +36 -0
- package/examples/quickstart/standalone/app/actions.ts +62 -0
- package/examples/quickstart/standalone/app/api/callback/route.ts +15 -0
- package/examples/quickstart/standalone/app/auth.ts +28 -0
- package/examples/quickstart/standalone/app/favicon.ico +0 -0
- package/examples/quickstart/standalone/app/globals.css +42 -0
- package/examples/quickstart/standalone/app/layout.tsx +32 -0
- package/examples/quickstart/standalone/app/page.module.css +200 -0
- package/examples/quickstart/standalone/app/page.tsx +53 -0
- package/examples/quickstart/standalone/auth/index.ts +32 -0
- package/examples/quickstart/standalone/auth/subjects.ts +8 -0
- package/examples/quickstart/standalone/bun.lockb +0 -0
- package/examples/quickstart/standalone/next.config.ts +7 -0
- package/examples/quickstart/standalone/package.json +25 -0
- package/examples/quickstart/standalone/public/file.svg +1 -0
- package/examples/quickstart/standalone/public/globe.svg +1 -0
- package/examples/quickstart/standalone/public/next.svg +1 -0
- package/examples/quickstart/standalone/public/vercel.svg +1 -0
- package/examples/quickstart/standalone/public/window.svg +1 -0
- package/examples/quickstart/standalone/tsconfig.json +27 -0
- package/examples/subjects.ts +8 -0
- package/examples/tsconfig.json +10 -0
- package/package.json +23 -0
- package/packages/openauth/CHANGELOG.md +310 -0
- package/packages/openauth/bunfig.toml +2 -0
- package/packages/openauth/package.json +51 -0
- package/packages/openauth/script/build.ts +25 -0
- package/packages/openauth/src/client-native.ts +204 -0
- package/packages/openauth/src/client.ts +776 -0
- package/packages/openauth/src/css.d.ts +4 -0
- package/packages/openauth/src/error.ts +120 -0
- package/packages/openauth/src/index.ts +26 -0
- package/packages/openauth/src/issuer.ts +1156 -0
- package/packages/openauth/src/jwt.ts +17 -0
- package/packages/openauth/src/keys.ts +139 -0
- package/packages/openauth/src/pkce.ts +40 -0
- package/packages/openauth/src/provider/apple.ts +127 -0
- package/packages/openauth/src/provider/arctic.ts +66 -0
- package/packages/openauth/src/provider/code.ts +227 -0
- package/packages/openauth/src/provider/cognito.ts +74 -0
- package/packages/openauth/src/provider/discord.ts +45 -0
- package/packages/openauth/src/provider/facebook.ts +84 -0
- package/packages/openauth/src/provider/github.ts +45 -0
- package/packages/openauth/src/provider/google.ts +85 -0
- package/packages/openauth/src/provider/index.ts +3 -0
- package/packages/openauth/src/provider/jumpcloud.ts +45 -0
- package/packages/openauth/src/provider/keycloak.ts +75 -0
- package/packages/openauth/src/provider/linkedin.ts +12 -0
- package/packages/openauth/src/provider/microsoft.ts +100 -0
- package/packages/openauth/src/provider/oauth2.ts +297 -0
- package/packages/openauth/src/provider/oidc.ts +179 -0
- package/packages/openauth/src/provider/password.ts +672 -0
- package/packages/openauth/src/provider/provider.ts +33 -0
- package/packages/openauth/src/provider/slack.ts +67 -0
- package/packages/openauth/src/provider/spotify.ts +45 -0
- package/packages/openauth/src/provider/twitch.ts +45 -0
- package/packages/openauth/src/provider/x.ts +46 -0
- package/packages/openauth/src/provider/yahoo.ts +45 -0
- package/packages/openauth/src/random.ts +28 -0
- package/packages/openauth/src/storage/aws.ts +59 -0
- package/packages/openauth/src/storage/cloudflare.ts +77 -0
- package/packages/openauth/src/storage/dynamo.ts +193 -0
- package/packages/openauth/src/storage/memory.ts +135 -0
- package/packages/openauth/src/storage/storage.ts +46 -0
- package/packages/openauth/src/subject.ts +130 -0
- package/packages/openauth/src/ui/base.tsx +118 -0
- package/packages/openauth/src/ui/code.tsx +212 -0
- package/packages/openauth/src/ui/form.tsx +40 -0
- package/packages/openauth/src/ui/icon.tsx +95 -0
- package/packages/openauth/src/ui/password.tsx +403 -0
- package/packages/openauth/src/ui/select.tsx +221 -0
- package/packages/openauth/src/ui/theme.ts +319 -0
- package/packages/openauth/src/ui/ui.css +252 -0
- package/packages/openauth/src/util.ts +58 -0
- package/packages/openauth/test/client-native.test.ts +30 -0
- package/packages/openauth/test/client.test.ts +177 -0
- package/packages/openauth/test/issuer.test.ts +393 -0
- package/packages/openauth/test/scrap.test.ts +85 -0
- package/packages/openauth/test/storage.test.ts +94 -0
- package/packages/openauth/test/util.test.ts +103 -0
- package/packages/openauth/tsconfig.json +13 -0
- package/scripts/format +15 -0
- package/www/.vscode/extensions.json +4 -0
- package/www/.vscode/launch.json +11 -0
- package/www/README.md +55 -0
- package/www/astro.config.mjs +136 -0
- package/www/bun.lockb +0 -0
- package/www/config.ts +4 -0
- package/www/generate.ts +911 -0
- package/www/package.json +24 -0
- package/www/public/favicon-dark.svg +3 -0
- package/www/public/favicon.ico +0 -0
- package/www/public/favicon.svg +3 -0
- package/www/public/social-share.png +0 -0
- package/www/src/assets/logo-dark.svg +11 -0
- package/www/src/assets/logo-light.svg +11 -0
- package/www/src/components/Hero.astro +11 -0
- package/www/src/components/Lander.astro +176 -0
- package/www/src/content/config.ts +6 -0
- package/www/src/content/docs/docs/client.mdx +650 -0
- package/www/src/content/docs/docs/index.mdx +325 -0
- package/www/src/content/docs/docs/issuer.mdx +512 -0
- package/www/src/content/docs/docs/provider/apple.mdx +233 -0
- package/www/src/content/docs/docs/provider/code.mdx +163 -0
- package/www/src/content/docs/docs/provider/cognito.mdx +173 -0
- package/www/src/content/docs/docs/provider/discord.mdx +139 -0
- package/www/src/content/docs/docs/provider/facebook.mdx +233 -0
- package/www/src/content/docs/docs/provider/github.mdx +139 -0
- package/www/src/content/docs/docs/provider/google.mdx +233 -0
- package/www/src/content/docs/docs/provider/jumpcloud.mdx +139 -0
- package/www/src/content/docs/docs/provider/keycloak.mdx +176 -0
- package/www/src/content/docs/docs/provider/microsoft.mdx +252 -0
- package/www/src/content/docs/docs/provider/oauth2.mdx +173 -0
- package/www/src/content/docs/docs/provider/oidc.mdx +113 -0
- package/www/src/content/docs/docs/provider/password.mdx +237 -0
- package/www/src/content/docs/docs/provider/slack.mdx +157 -0
- package/www/src/content/docs/docs/provider/spotify.mdx +139 -0
- package/www/src/content/docs/docs/provider/twitch.mdx +139 -0
- package/www/src/content/docs/docs/provider/x.mdx +139 -0
- package/www/src/content/docs/docs/provider/yahoo.mdx +139 -0
- package/www/src/content/docs/docs/start/nextjs-dark.png +0 -0
- package/www/src/content/docs/docs/start/nextjs-light.png +0 -0
- package/www/src/content/docs/docs/start/sst.mdx +423 -0
- package/www/src/content/docs/docs/start/standalone.mdx +376 -0
- package/www/src/content/docs/docs/storage/cloudflare.mdx +63 -0
- package/www/src/content/docs/docs/storage/dynamo.mdx +127 -0
- package/www/src/content/docs/docs/storage/memory.mdx +77 -0
- package/www/src/content/docs/docs/subject.mdx +139 -0
- package/www/src/content/docs/docs/themes-dark.png +0 -0
- package/www/src/content/docs/docs/themes-light.png +0 -0
- package/www/src/content/docs/docs/ui/code.mdx +248 -0
- package/www/src/content/docs/docs/ui/password.mdx +410 -0
- package/www/src/content/docs/docs/ui/select.mdx +99 -0
- package/www/src/content/docs/docs/ui/theme.mdx +284 -0
- package/www/src/content/docs/index.mdx +12 -0
- package/www/src/custom.css +0 -0
- package/www/src/env.d.ts +2 -0
- package/www/src/styles/lander.css +15 -0
- package/www/tsconfig.json +3 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": "./commit.cjs",
|
|
5
|
+
"fixed": [["@farmsdotmarket/openauth"]],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "public",
|
|
8
|
+
"baseBranch": "master",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": ["@openauthjs/example-*"]
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@farmsdotmarket/openauth": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Farms fork maintenance release:
|
|
6
|
+
|
|
7
|
+
- keep React Native-safe `@openauthjs/openauth/client` export condition
|
|
8
|
+
- keep RN-safe client entrypoint (`authorize`, `exchange`, `refresh`)
|
|
9
|
+
- keep non-Node timing-safe compare path in random utilities
|
|
10
|
+
- keep issuer client URL hardening guardrails
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
I don't typically set up a code of conduct for our projects but given this one is security related it will draw a very specific set of problems I want to avoid. There's only two rules
|
|
4
|
+
|
|
5
|
+
1. Reporting security issues
|
|
6
|
+
|
|
7
|
+
If you find a security issue please report them to me directly on [X](https://twitter.com/thdxr) or [Bluesky](https://bsky.app/). Do not open a public issue or post publicly in case the issue can be exploited. Feel free to give us a window of time to respond before disclosing it publicly - that seems fair.
|
|
8
|
+
|
|
9
|
+
2. Reporting "security" issues
|
|
10
|
+
|
|
11
|
+
A lot of things that seem to fall in that first category are not really security problems, just tradeoffs that were made in the design of OpenAuth. Security products attract a lot of binary opinions like "never use X". We reject this type of thinking entirely - security is a spectrum of usability and infinitely optimizing for "security" does not yield a good product.
|
|
12
|
+
|
|
13
|
+
All discussions around the tradeoffs that were made must consider this - if you disagree with a decision you MUST articulate why the decision was probably made before you argue against it. Eg. "X seem to be used because of benefit [a] and their downside [b] is mitigated by [c] BUT I do not think this is enough because of [d]"
|
|
14
|
+
|
|
15
|
+
We do not tolerate wasting the maintainers time and forcing them to articulate this nuance. If something is not clear of course you can ask for clarification.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# Trigger the workflow every time you push to the `main` branch
|
|
5
|
+
# Using a different branch name? Replace `main` with your branch’s name
|
|
6
|
+
push:
|
|
7
|
+
branches: [master]
|
|
8
|
+
# Allows you to run this workflow manually from the Actions tab on GitHub.
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
# Allow this job to clone the repo and create a page deployment
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
pages: write
|
|
15
|
+
id-token: write
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- name: Checkout your repository using git
|
|
22
|
+
uses: actions/checkout@v4
|
|
23
|
+
- name: Install, build, and upload your site
|
|
24
|
+
uses: withastro/action@v3
|
|
25
|
+
with:
|
|
26
|
+
path: www
|
|
27
|
+
|
|
28
|
+
deploy:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment:
|
|
32
|
+
name: github-pages
|
|
33
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
34
|
+
steps:
|
|
35
|
+
- name: Deploy to GitHub Pages
|
|
36
|
+
id: deployment
|
|
37
|
+
uses: actions/deploy-pages@v4
|
|
38
|
+
with:
|
|
39
|
+
path: www
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: format
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
format:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
pull-requests: write
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
ref: ${{ github.head_ref }}
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
- uses: oven-sh/setup-bun@v2
|
|
23
|
+
- run: |
|
|
24
|
+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
25
|
+
git config --local user.name "github-actions[bot]"
|
|
26
|
+
./scripts/format
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release:
|
|
16
|
+
name: release
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v3
|
|
20
|
+
- uses: oven-sh/setup-bun@v2
|
|
21
|
+
- run: bun install
|
|
22
|
+
- id: changesets
|
|
23
|
+
uses: changesets/action@v1
|
|
24
|
+
with:
|
|
25
|
+
publish: bun run release
|
|
26
|
+
env:
|
|
27
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: oven-sh/setup-bun@v2
|
|
16
|
+
with:
|
|
17
|
+
bun-version: latest
|
|
18
|
+
- run: bun install
|
|
19
|
+
- run: cd packages/openauth && bun run build
|
|
20
|
+
- run: cd packages/openauth && bun test
|
package/.prettierrc
ADDED
package/CNAME
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
openauth.js.org
|
package/FARMS_RELEASE.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Farms OpenAuth Release Runbook
|
|
2
|
+
|
|
3
|
+
This fork currently tracks `farms/react-native-client` and is consumed by Farms.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Publish a consumable npm package release so downstream apps do not need git-monorepo dependency tricks.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- npm token with publish permissions
|
|
12
|
+
- git push rights to this fork
|
|
13
|
+
- Bun available locally
|
|
14
|
+
|
|
15
|
+
## 1) Prepare branch
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git checkout farms/react-native-client
|
|
19
|
+
git pull --ff-only
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 2) Install and verify
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bun install
|
|
26
|
+
cd packages/openauth
|
|
27
|
+
bun test
|
|
28
|
+
bun run build
|
|
29
|
+
cd ../..
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 3) Version the package
|
|
33
|
+
|
|
34
|
+
This repo already includes a pending changeset for a Farms patch release.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bunx changeset version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Expected updates include:
|
|
41
|
+
|
|
42
|
+
- `packages/openauth/package.json` version bump (eg `0.4.3-farms.2`)
|
|
43
|
+
- `packages/openauth/CHANGELOG.md` entry
|
|
44
|
+
|
|
45
|
+
## 4) Publish
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bun run release
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Release workflow notes:
|
|
52
|
+
|
|
53
|
+
- Root `release` runs build for `@farmsdotmarket/openauth` then `changeset publish`.
|
|
54
|
+
- Ensure `NPM_TOKEN` is configured in your shell or CI.
|
|
55
|
+
|
|
56
|
+
## 5) Update Farms consumer repo
|
|
57
|
+
|
|
58
|
+
After publish, in Farms:
|
|
59
|
+
|
|
60
|
+
1. Replace git dependency pins with published npm version in:
|
|
61
|
+
- `package.json`
|
|
62
|
+
- `packages/auth/package.json`
|
|
63
|
+
- `packages/lambda/package.json`
|
|
64
|
+
- `packages/mobile/package.json`
|
|
65
|
+
- `packages/web/package.json`
|
|
66
|
+
2. Reinstall lockfile (`pnpm install`).
|
|
67
|
+
3. Validate imports:
|
|
68
|
+
- `@openauthjs/openauth`
|
|
69
|
+
- `@openauthjs/openauth/client`
|
|
70
|
+
- `@openauthjs/openauth/subject`
|
|
71
|
+
4. Run `pnpm -r typecheck`.
|
|
72
|
+
5. Run SST build path (`sst dev` or deploy preview).
|
|
73
|
+
|
|
74
|
+
## Consume in Farms (keep current imports)
|
|
75
|
+
|
|
76
|
+
Use npm aliasing in consumer manifests:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
"@openauthjs/openauth": "npm:@farmsdotmarket/openauth@0.4.3-farms.2"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This preserves all existing import paths in application code.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 SST
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/PATCHES.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Farms OpenAuth Fork Patches
|
|
2
|
+
|
|
3
|
+
This fork branch contains Farms-specific patches for React Native compatibility and security hardening.
|
|
4
|
+
|
|
5
|
+
## 1) React Native client export and mobile-safe client entry
|
|
6
|
+
- Fork patch:
|
|
7
|
+
- Added `./client` export condition with `react-native` target in `packages/openauth/package.json`.
|
|
8
|
+
- Added `packages/openauth/src/client-native.ts` with a minimal mobile-safe surface:
|
|
9
|
+
- `authorize`
|
|
10
|
+
- `exchange`
|
|
11
|
+
- `refresh`
|
|
12
|
+
- Added `packages/openauth/test/client-native.test.ts`.
|
|
13
|
+
- Upstream related work:
|
|
14
|
+
- https://github.com/anomalyco/openauth/pull/222 (Expo/React Native example)
|
|
15
|
+
- https://github.com/anomalyco/openauth/pull/136 (platform-specific dependency cleanup)
|
|
16
|
+
|
|
17
|
+
## 2) Runtime import portability fix for timing-safe compare
|
|
18
|
+
- Fork patch:
|
|
19
|
+
- Replaced Node-only `node:crypto` import in `packages/openauth/src/random.ts`.
|
|
20
|
+
- Implemented runtime-agnostic constant-time string compare for equal-length strings.
|
|
21
|
+
- Upstream related work:
|
|
22
|
+
- https://github.com/anomalyco/openauth/pull/93 (OTP bias and timing attack work)
|
|
23
|
+
- https://github.com/anomalyco/openauth/pull/136 (platform-specific dependency cleanup)
|
|
24
|
+
|
|
25
|
+
## 3) Client issuer security guardrails
|
|
26
|
+
- Fork patch:
|
|
27
|
+
- Added issuer validation in `packages/openauth/src/client.ts` and `packages/openauth/src/client-native.ts`.
|
|
28
|
+
- Requires `https` issuer except for localhost/loopback development hosts.
|
|
29
|
+
- Added tests in `packages/openauth/test/client.test.ts`.
|
|
30
|
+
- Upstream related work:
|
|
31
|
+
- https://github.com/anomalyco/openauth/pull/305 (redirect URI security hardening)
|
|
32
|
+
- https://github.com/anomalyco/openauth/pull/309 (JWT audience validation hardening)
|
package/README.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://openauth.js.org">
|
|
3
|
+
<picture>
|
|
4
|
+
<source srcset="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/logo-dark.svg" media="(prefers-color-scheme: dark)">
|
|
5
|
+
<source srcset="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/logo-light.svg" media="(prefers-color-scheme: light)">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/logo-light.svg" alt="OpenAuth logo">
|
|
7
|
+
</picture>
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://sst.dev/discord"><img alt="Discord" src="https://img.shields.io/discord/983865673656705025?style=flat-square&label=Discord" /></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/@openauthjs/openauth"><img alt="npm" src="https://img.shields.io/npm/v/%40openauthjs%2Fcore?style=flat-square" /></a>
|
|
13
|
+
<a href="https://github.com/toolbeam/openauth/actions/workflows/release.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/toolbeam/openauth/release.yml?style=flat-square&branch=master" /></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
[OpenAuth](https://openauth.js.org) is a standards-based auth provider for web apps, mobile apps, single pages apps, APIs, or 3rd party clients. It is currently in beta.
|
|
19
|
+
|
|
20
|
+
- **Universal**: You can deploy it as a standalone service or embed it into an existing application. It works with any framework or platform.
|
|
21
|
+
- **Self-hosted**: It runs entirely on your infrastructure and can be deployed on Node.js, Bun, AWS Lambda, or Cloudflare Workers.
|
|
22
|
+
- **Standards-based**: It implements the OAuth 2.0 spec and is based on web standards. So any OAuth client can use it.
|
|
23
|
+
- **Customizable**: It comes with prebuilt themeable UI that you can customize or opt out of.
|
|
24
|
+
|
|
25
|
+
<picture>
|
|
26
|
+
<source srcset="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/assets/themes-dark.png" media="(prefers-color-scheme: dark)">
|
|
27
|
+
<source srcset="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/assets/themes-light.png" media="(prefers-color-scheme: dark)">
|
|
28
|
+
<img src="https://raw.githubusercontent.com/toolbeam/identity/main/openauth/assets/themes-light.png" alt="OpenAuth themes">
|
|
29
|
+
</picture>
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
If you just want to get started as fast as possible you can jump straight into the [code examples](https://github.com/toolbeam/openauth/tree/master/examples) folder and copy paste away. There are also [SST components](https://sst.dev/docs/component/aws/auth) for deploying everything OpenAuth needs.
|
|
34
|
+
|
|
35
|
+
## Approach
|
|
36
|
+
|
|
37
|
+
While there are many open source solutions for auth, almost all of them are libraries that are meant to be embedded into a single application. Centralized auth servers typically are delivered as SaaS services - eg Auth0 or Clerk.
|
|
38
|
+
|
|
39
|
+
OpenAuth instead is a centralized auth server that runs on your own infrastructure and has been designed for ease of self hosting. It can be used to authenticate all of your applications - web apps, mobile apps, internal admin tools, etc.
|
|
40
|
+
|
|
41
|
+
It adheres mostly to OAuth 2.0 specifications - which means anything that can speak OAuth can use it to receive access and refresh tokens. When a client initiates an authorization flow, OpenAuth will hand off to one of the configured providers - this can be third party identity providers like Google, GitHub, etc or built in flows like email/password or pin code.
|
|
42
|
+
|
|
43
|
+
Because it follows these specifications it can even be used to issue credentials for third party applications - allowing you to implement "login with myapp" flows.
|
|
44
|
+
|
|
45
|
+
OpenAuth very intentionally does not attempt to solve user management. We've found that this is a very difficult problem given the wide range of databases and drivers that are used in the JS ecosystem. Additionally it's quite hard to build data abstractions that work for every use case. Instead, once a user has identified themselves OpenAuth will invoke a callback where you can implement your own user lookup/creation logic.
|
|
46
|
+
|
|
47
|
+
While OpenAuth tries to be mostly stateless, it does need to store a minimal amount of data (refresh tokens, password hashes, etc). However this has been reduced to a simple KV store with various implementations for zero overhead systems like Cloudflare KV and DynamoDB. You should never need to directly access any data that is stored in there.
|
|
48
|
+
|
|
49
|
+
There is also a themeable UI that you can use to get going without implementing any designs yourself. This is built on top of a lower level system so you can copy paste the default UI and tweak it or opt out entirely and implement your own.
|
|
50
|
+
|
|
51
|
+
Finally, OpenAuth is created by the maintainers of [SST](https://sst.dev) which is a tool to manage all the infrastructure for your app. It contains components for OpenAuth that make deploying it to AWS or Cloudflare as simple as it can get.
|
|
52
|
+
|
|
53
|
+
## Tutorial
|
|
54
|
+
|
|
55
|
+
We'll show how to deploy the auth server and then a sample app that uses it.
|
|
56
|
+
|
|
57
|
+
### Auth server
|
|
58
|
+
|
|
59
|
+
Start by importing the `issuer` function from the `@openauthjs/openauth` package.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { issuer } from "@openauthjs/openauth"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
OpenAuth is built on top of [Hono](https://github.com/honojs/hono) which is a minimal web framework that can run anywhere. The `issuer` function creates a Hono app with all of the auth server implemented that you can then deploy to AWS Lambda, Cloudflare Workers, or in a container running under Node.js or Bun.
|
|
66
|
+
|
|
67
|
+
The `issuer` function requires a few things:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const app = issuer({
|
|
71
|
+
providers: { ... },
|
|
72
|
+
storage,
|
|
73
|
+
subjects,
|
|
74
|
+
success: async (ctx, value) => { ... }
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
First we need to define some providers that are enabled - these are either third party identity providers like Google, GitHub, etc or built in flows like email/password or pin code. You can also implement your own. Let's try the GitHub provider.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { GithubProvider } from "@openauthjs/openauth/provider/github"
|
|
82
|
+
|
|
83
|
+
const app = issuer({
|
|
84
|
+
providers: {
|
|
85
|
+
github: GithubProvider({
|
|
86
|
+
clientID: process.env.GITHUB_CLIENT_ID!,
|
|
87
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
88
|
+
scopes: ["user:email"],
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
...
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Providers take some configuration - since this is a third party identity provider there is no UI to worry about and all it needs is a client ID, secret and some scopes. Let's add the password provider which is a bit more complicated.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { PasswordProvider } from "@openauthjs/openauth/provider/password"
|
|
99
|
+
|
|
100
|
+
const app = issuer({
|
|
101
|
+
providers: {
|
|
102
|
+
github: ...,
|
|
103
|
+
password: PasswordProvider(...),
|
|
104
|
+
},
|
|
105
|
+
...
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The password provider is quite complicated as username/password involve a lot of flows so there are a lot of callbacks to implement. However you can opt into the default UI which has all of this already implemented for you. The only thing you have to specify is how to send a code for forgot password/email verification. In this case we'll log the code but you would send this over email.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { PasswordProvider } from "@openauthjs/openauth/provider/password"
|
|
113
|
+
import { PasswordUI } from "@openauthjs/openauth/ui/password"
|
|
114
|
+
|
|
115
|
+
const app = issuer({
|
|
116
|
+
providers: {
|
|
117
|
+
github: ...,
|
|
118
|
+
password: PasswordProvider(
|
|
119
|
+
PasswordUI({
|
|
120
|
+
sendCode: async (email, code) => {
|
|
121
|
+
console.log(email, code)
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
),
|
|
125
|
+
},
|
|
126
|
+
...
|
|
127
|
+
})
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Next up is the `subjects` field. Subjects are what the access token generated at the end of the auth flow will map to. Under the hood, the access token is a JWT that contains this data. You will likely just have a single subject to start but you can define additional ones for different types of users.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { object, string } from "valibot"
|
|
134
|
+
|
|
135
|
+
const subjects = createSubjects({
|
|
136
|
+
user: object({
|
|
137
|
+
userID: string(),
|
|
138
|
+
// may want to add workspaceID here if doing a multi-tenant app
|
|
139
|
+
workspaceID: string(),
|
|
140
|
+
}),
|
|
141
|
+
})
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Note we are using [valibot](https://github.com/fabian-hiller/valibot) to define the shape of the subject so it can be validated properly. You can use any validation library that is following the [standard-schema specification](https://github.com/standard-schema/standard-schema) - the next version of Zod will support this.
|
|
145
|
+
|
|
146
|
+
You typically will want to place subjects in its own file as it can be imported by all of your apps. You can pass it to the issuer in the `subjects` field.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { subjects } from "./subjects.js"
|
|
150
|
+
|
|
151
|
+
const app = issuer({
|
|
152
|
+
providers: { ... },
|
|
153
|
+
subjects,
|
|
154
|
+
...
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Next we'll implement the `success` callback which receives the payload when a user successfully completes a provider flow.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const app = issuer({
|
|
162
|
+
providers: { ... },
|
|
163
|
+
subjects,
|
|
164
|
+
async success(ctx, value) {
|
|
165
|
+
let userID
|
|
166
|
+
if (value.provider === "password") {
|
|
167
|
+
console.log(value.email)
|
|
168
|
+
userID = ... // lookup user or create them
|
|
169
|
+
}
|
|
170
|
+
if (value.provider === "github") {
|
|
171
|
+
console.log(value.tokenset.access)
|
|
172
|
+
userID = ... // lookup user or create them
|
|
173
|
+
}
|
|
174
|
+
return ctx.subject("user", {
|
|
175
|
+
userID,
|
|
176
|
+
'a workspace id'
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Note all of this is typesafe - based on the configured providers you will receive different properties in the `value` object. Also the `subject` method will only accept properties. Note - most callbacks in OpenAuth can return a `Response` object. In this case if something goes wrong, you can return a `Response.redirect("...")` sending them to a different place or rendering an error.
|
|
183
|
+
|
|
184
|
+
Next we have the `storage` field which defines where things like refresh tokens and password hashes are stored. If on AWS we recommend DynamoDB, if on Cloudflare we recommend Cloudflare KV. We also have a MemoryStore used for testing.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { MemoryStorage } from "@openauthjs/openauth/storage/memory"
|
|
188
|
+
|
|
189
|
+
const app = issuer({
|
|
190
|
+
providers: { ... },
|
|
191
|
+
subjects,
|
|
192
|
+
async success(ctx, value) { ... },
|
|
193
|
+
storage: MemoryStorage(),
|
|
194
|
+
})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
And now we are ready to deploy! Here's how you do that depending on your infrastructure.
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
// Bun
|
|
201
|
+
export default app
|
|
202
|
+
|
|
203
|
+
// Cloudflare
|
|
204
|
+
export default app
|
|
205
|
+
|
|
206
|
+
// Lambda
|
|
207
|
+
import { handle } from "hono/aws-lambda"
|
|
208
|
+
export const handler = handle(app)
|
|
209
|
+
|
|
210
|
+
// Node.js
|
|
211
|
+
import { serve } from "@hono/node-server"
|
|
212
|
+
serve(app)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
You now have a centralized auth server. Test it out by visiting `/.well-known/oauth-authorization-server` - you can see a live example [here](https://auth.terminal.shop/.well-known/oauth-authorization-server).
|
|
216
|
+
|
|
217
|
+
### Auth client
|
|
218
|
+
|
|
219
|
+
Since this is a standard OAuth server you can use any libraries for OAuth and it will work. OpenAuth does provide some light tooling for this although even a manual flow is pretty simple. You can create a client like this:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { createClient } from "@openauthjs/openauth/client"
|
|
223
|
+
|
|
224
|
+
const client = createClient({
|
|
225
|
+
clientID: "my-client",
|
|
226
|
+
issuer: "https://auth.myserver.com", // url to the OpenAuth server
|
|
227
|
+
})
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### SSR Sites
|
|
231
|
+
|
|
232
|
+
If your frontend has a server component you can use the code flow. Redirect the user here
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const { url } = await client.authorize(
|
|
236
|
+
<redirect-uri>,
|
|
237
|
+
"code"
|
|
238
|
+
)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
You can make up a `client_id` that represents your app. This will initiate the auth flow and user will be redirected to the `redirect_uri` you provided with a query parameter `code` which you can exchange for an access token.
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
// the redirect_uri is the original redirect_uri you passed in and is used for verification
|
|
245
|
+
const tokens = await client.exchange(query.get("code"), redirect_uri)
|
|
246
|
+
console.log(tokens.access, tokens.refresh)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
You likely want to store both the access token and refresh token in an HTTP only cookie so they are sent up with future requests. Then you can use the `client` to verify the tokens.
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const verified = await client.verify(subjects, cookies.get("access_token")!, {
|
|
253
|
+
refresh: cookies.get("refresh_token") || undefined,
|
|
254
|
+
})
|
|
255
|
+
console.log(
|
|
256
|
+
verified.subject.type,
|
|
257
|
+
verified.subject.properties,
|
|
258
|
+
verified.refresh,
|
|
259
|
+
verified.access,
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Passing in the refresh token is optional but if you do, this function will automatically refresh the access token if it has expired. It will return a new access token and refresh token which you should set back into the cookies.
|
|
264
|
+
|
|
265
|
+
#### SPA Sites, Mobile apps, etc
|
|
266
|
+
|
|
267
|
+
In cases where you do not have a server, you can use the `token` flow with `pkce` on the frontend.
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const { challenge, url } = await client.authorize(<redirect_uri>, "code", { pkce: true })
|
|
271
|
+
localStorage.setItem("challenge", JSON.stringify(challenge))
|
|
272
|
+
location.href = url
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
When the auth flow is complete the user's browser will be redirected to the `redirect_uri` with a `code` query parameter. You can then exchange the code for access/refresh tokens.
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
const challenge = JSON.parse(localStorage.getItem("challenge"))
|
|
279
|
+
const exchanged = await client.exchange(
|
|
280
|
+
query.get("code"),
|
|
281
|
+
redirect_uri,
|
|
282
|
+
challenge.verifier,
|
|
283
|
+
)
|
|
284
|
+
if (exchanged.err) throw new Error("Invalid code")
|
|
285
|
+
localStorage.setItem("access_token", exchanged.tokens.access)
|
|
286
|
+
localStorage.setItem("refresh_token", exchanged.tokens.refresh)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Then when you make requests to your API you can include the access token in the `Authorization` header.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
const accessToken = localStorage.getItem("access_token")
|
|
293
|
+
fetch("https://auth.example.com/api/user", {
|
|
294
|
+
headers: {
|
|
295
|
+
Authorization: `Bearer ${accessToken}`,
|
|
296
|
+
},
|
|
297
|
+
})
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
And then you can verify the access token on the server.
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
const verified = await client.verify(subjects, accessToken)
|
|
304
|
+
console.log(verified.subject)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
OpenAuth is created by the maintainers of [SST](https://sst.dev).
|
|
310
|
+
|
|
311
|
+
**Join our community** [Discord](https://sst.dev/discord) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev)
|
package/bun.lockb
ADDED
|
Binary file
|
package/bunfig.toml
ADDED