Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production release #16

Merged
merged 51 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8153fbc
⬆️ Upgrade deps
cermakjiri Nov 9, 2024
4b83a2e
🔒️ Include dev deps in npm audit
cermakjiri Nov 9, 2024
0cfe6ac
🔧 Set nmMode in yarnrc
cermakjiri Nov 9, 2024
6eb83d9
✨ Extract sentry configs to @workspace/sentry
cermakjiri Nov 9, 2024
8538ec5
🚚 Extract Passkeys components to the @workspace/common
cermakjiri Nov 16, 2024
d886145
⬆️ turbo
cermakjiri Nov 16, 2024
a89b5e4
✨ Add upgrade to passkeys example
cermakjiri Nov 21, 2024
33881f7
⬆️ Upgrade dependencies
cermakjiri Nov 21, 2024
6a706a2
Feat/webauthn upgrade example (#12)
cermakjiri Nov 21, 2024
6de304d
👷 Extend CI for preview deployment
cermakjiri Nov 21, 2024
d688a10
💚 Fix CI
cermakjiri Nov 21, 2024
076f245
💚 Fix CI
cermakjiri Nov 21, 2024
2855009
👷 Update CI workflow to include checkout step for preview jobs
cermakjiri Nov 21, 2024
b512a4c
👷 Update preview workflow jobs to use consistent naming and specify r…
cermakjiri Nov 21, 2024
2ad727c
💚 Update CI
cermakjiri Nov 21, 2024
a7b82dc
👷 Update CI
cermakjiri Nov 21, 2024
77d9785
👷 CI
cermakjiri Nov 21, 2024
c071a4f
CI
cermakjiri Nov 21, 2024
1cab6da
CI
cermakjiri Nov 21, 2024
cabe1b1
CI
cermakjiri Nov 21, 2024
93f4262
Update CI
cermakjiri Nov 21, 2024
e908d56
👷 Extend production workflow
cermakjiri Nov 21, 2024
dbd76cb
🐛 Add missing eslint config
cermakjiri Nov 21, 2024
29e8f9a
🐛 Fix build issues
cermakjiri Nov 21, 2024
c913096
⚡️ Improve build config
cermakjiri Nov 21, 2024
0de8110
👷 CI
cermakjiri Nov 21, 2024
352c026
Update login error response
cermakjiri Nov 21, 2024
96965f2
🐛 Add SENTRY_AUTH_TOKEN requirement to workflows
cermakjiri Nov 21, 2024
288cf0b
♻️ Add SENTRY_AUTH_TOKEN to Sentry configuration and log Sentry details
cermakjiri Nov 21, 2024
9d40d4b
✨ Handle email code verification in the app
cermakjiri Nov 22, 2024
c13bbe0
✨ Handle email code verification in the app (#13)
cermakjiri Nov 22, 2024
a0410b8
📝 Updat READMEs
cermakjiri Nov 22, 2024
1d5e53c
✨ Add feedback integration to Sentry client configuration
cermakjiri Nov 22, 2024
8f8e421
♻️ Refactor Vercel secrets handling in GitHub Actions workflow
cermakjiri Nov 22, 2024
5f9e582
♻️ Fix syntax for accessing secrets in GitHub Actions workflow
cermakjiri Nov 22, 2024
a020429
♻️ Update GitHub Actions workflow to use secrets syntax for Vercel co…
cermakjiri Nov 22, 2024
995145c
♻️ Refactor GitHub Actions workflows to use inputs instead of secrets…
cermakjiri Nov 22, 2024
61dfe72
♻️ Refactor GitHub Actions workflows to use secrets for Vercel token …
cermakjiri Nov 22, 2024
82957fa
CI
cermakjiri Nov 22, 2024
c3637e8
CI
cermakjiri Nov 22, 2024
77a08f0
♻️ Update GitHub Actions workflows to use secrets for Sentry authenti…
cermakjiri Nov 22, 2024
4c1e724
⬆️ node & yarn
cermakjiri Nov 27, 2024
46f19c2
♻️ Update GitHub Actions workflows to use secrets for Sentry authenti…
cermakjiri Nov 27, 2024
086b774
♻️ Fix registration flow in the upgrade example
cermakjiri Nov 28, 2024
61c8573
🏷️ Fix type
cermakjiri Nov 28, 2024
69569e7
✨ Add link to Github to each example
cermakjiri Nov 28, 2024
ad76efb
✨ Add side menu with list of all examples
cermakjiri Nov 28, 2024
e34fc49
🐛 Fix types-checking
cermakjiri Nov 28, 2024
2d3198c
Bump cross-spawn from 7.0.4 to 7.0.6
dependabot[bot] Nov 28, 2024
9718ef2
Bump cross-spawn from 7.0.4 to 7.0.6 (#15)
cermakjiri Nov 28, 2024
0923cb1
🔧 Enable envs check in CI
cermakjiri Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Each demo has separate origin due to relying party restrictions (https://webauthn.wtf/how-it-works/relying-party)
NEXT_PUBLIC_DEFAULT_EXAMPLE_ORIGIN="http://localhost:3000"
NEXT_PUBLIC_UPGRADE_EXAMPLE_ORIGIN="http://localhost:3001"
44 changes: 44 additions & 0 deletions .github/workflows/preview-common.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Reusable Preview Workflow

on:
workflow_call:
inputs:
vercel_project_name:
required: true
type: string
vercel_scope:
required: true
type: string

secrets:
VERCEL_TOKEN:
required: true
SENTRY_AUTH_TOKEN:
required: true

jobs:
shared-steps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22

- name: Enable Corepack
run: corepack enable

- name: Install Corepack
run: corepack install

- name: Link Project to Vercel
run: yarn dlx -q vercel link --project=${{ inputs.vercel_project_name }} --scope=${{ inputs.vercel_scope }} --yes --token=${{ secrets.VERCEL_TOKEN }}

- name: Pull Vercel Environment Information
run: yarn dlx -q vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: yarn dlx -q vercel build --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy Project Artifacts to Vercel
run: yarn dlx -q vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
44 changes: 14 additions & 30 deletions .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
name: Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_SCOPE: ${{ secrets.VERCEL_SCOPE }}
VERCEL_PROJECT_NAME: ${{ secrets.VERCEL_PROJECT_NAME }}

on:
push:
branches:
- dev
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20

- name: Enable Corepack
run: corepack enable

- name: Install Corepack
run: corepack install

- name: Link Project to Vercel
run: yarn dlx -q vercel link --project=$VERCEL_PROJECT_NAME --scope=$VERCEL_SCOPE --yes --token=$VERCEL_TOKEN

- name: Pull Vercel Environment Information
run: yarn dlx -q vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: yarn dlx -q vercel build --token=${{ secrets.VERCEL_TOKEN }}
jobs:
default-example:
uses: ./.github/workflows/preview-common.yaml
secrets: inherit
with:
vercel_project_name: ${{ vars.VERCEL_PROJECT_DEFAULT }}
vercel_scope: ${{ vars.VERCEL_SCOPE }}

- name: Deploy Project Artifacts to Vercel
run: yarn dlx -q vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
upgrade-example:
uses: ./.github/workflows/preview-common.yaml
secrets: inherit
with:
vercel_project_name: ${{ vars.VERCEL_PROJECT_UPGRADE }}
vercel_scope: ${{ vars.VERCEL_SCOPE }}
44 changes: 44 additions & 0 deletions .github/workflows/production-common.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Reusable Production Workflow

on:
workflow_call:
inputs:
vercel_project_name:
required: true
type: string
vercel_scope:
required: true
type: string

secrets:
VERCEL_TOKEN:
required: true
SENTRY_AUTH_TOKEN:
required: true

jobs:
shared-steps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22

- name: Enable Corepack
run: corepack enable

- name: Install Corepack
run: corepack install

- name: Link Project to Vercel
run: yarn dlx -q vercel link --project=${{ inputs.vercel_project_name }} --scope=${{ inputs.vercel_scope }} --yes --token=${{ secrets.VERCEL_TOKEN }}

- name: Pull Vercel Environment Information
run: yarn dlx -q vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: yarn dlx -q vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy Project Artifacts to Vercel
run: yarn dlx -q vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
43 changes: 13 additions & 30 deletions .github/workflows/production.yaml
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
name: Vercel Production Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_SCOPE: ${{ secrets.VERCEL_SCOPE }}
VERCEL_PROJECT_NAME: ${{ secrets.VERCEL_PROJECT_NAME }}

on:
push:
branches:
- main
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20

- name: Enable Corepack
run: corepack enable

- name: Install Corepack
run: corepack install

- name: Link Project to Vercel
run: yarn dlx -q vercel link --project=$VERCEL_PROJECT_NAME --scope=$VERCEL_SCOPE --yes --token=$VERCEL_TOKEN

- name: Pull Vercel Environment Information
run: yarn dlx -q vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: yarn dlx -q vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
jobs:
default-example:
uses: ./.github/workflows/production-common.yaml
secrets: inherit
with:
vercel_project_name: ${{ vars.VERCEL_PROJECT_DEFAULT }}
vercel_scope: ${{ vars.VERCEL_SCOPE }}

- name: Deploy Project Artifacts to Vercel
run: yarn dlx -q vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
upgrade-example:
uses: ./.github/workflows/production-common.yaml
with:
vercel_project_name: ${{ secrets.VERCEL_PROJECT_UPGRADE }}
vercel_scope: ${{ vars.VERCEL_SCOPE }}
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.18.0
22.11.0
4 changes: 3 additions & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
compressionLevel: 0

defaultSemverRangePrefix: ""
defaultSemverRangePrefix: ''

enableHardenedMode: true

Expand All @@ -17,3 +17,5 @@ nmSelfReferences: false
nodeLinker: node-modules

preferInteractive: true

nmMode: hardlinks-global
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,37 @@

# With WebAuthn

A repository with full stack WebAuthn API examples.
A repository with full stack **WebAuthn API** examples.

<div style="text-align:left">

## Examples

1. **[Default WebAuthn Example - Passkeys with SimpleWebAuthn & Firebase](examples/webauthn-default/README.md)**
1. **[Authenticate with passkeys - Passkeys with SimpleWebAuthn & Firebase](examples/webauthn-default/README.md)**

- Creating (user registration), retrieving (user login), linking multiple, and removing passkeys.
- Issuing a JWT token via Firebase Auth once user is authenticated.
- Passkes are stored in Firebase Firestore.
- Formatting and parsing of WebAuthn API request / responses done via SimpleWebAuthn library.
- Passkeys autofill.
- Formatting and parsing of WebAuthn API request / responses done via [SimpleWebAuthn](https://simplewebauthn.dev) library.
- Built with [Firebase Auth](https://firebase.google.com/docs/auth/admin/create-custom-tokens) and Firestore SDKs.
- 👉 [**Check out the demo**](https://with-webauthn.dev)

2. **[Upgrade to passkeys – From email/password to passkeys with SimpleWebAuthn & Firebase](examples/webauthn-upgrade/README.md)**
- A user registers with traditional email/password and verifies their email afterwards.
- Then the user can link passkey/s and therefore upgrades to MFA.
- The user can downgrade to single-factor authentication by removing all their passkeys.
- Built with [SimpleWebAuthn](https://simplewebauthn.dev), [Firebase Auth](https://firebase.google.com/docs/auth/admin/create-custom-tokens) and Firestore SDKs.
- 👉 [**Check out the demo**](https://upgrade.with-webauthn.dev)

---

## Development

### Common Stack notes:

- The whole project is managed using tuborepo and yarn workspaces.
- The whole project is managed using tuborepo.
- All examples are in NextJS (React) framework.
- API calls are handled with React Tanstack query on client.
- API endpoints are build via NextJS API routes.
- API endpoints are built via NextJS API routes.
- Forms are built with react-hook-form and validated with zod schemas.
- Material UI with styled components as UI SDK.

Expand All @@ -46,8 +54,11 @@ A repository with full stack WebAuthn API examples.
yarn install --immutable
```

3. Then continue with final steps for specific example:
- [Passkeys with SimpleWebAuthn & Firebase](examples/webauthn-default/README.md)
3. Note that common code of each example is placed in `packages/common` (for client and server).

4. Then continue with final steps for specific example:
- [Authenticate with passkeys](examples/webauthn-default/README.md)
- [Upgrade to passkeys](examples/webauthn-upgrade/README.md)

## Have you a found a bug?

Expand Down
30 changes: 28 additions & 2 deletions examples/webauthn-default/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Default WebAuthn Example - Passkeys with SimpleWebAuthn & Firebase
# Authenticate with passkeys example - Passkeys with SimpleWebAuthn & Firebase

- Creating (user registration), retrieving (user login), linking multiple, and removing passkeys.
- Issuing a JWT token via Firebase Auth once user is authenticated.
Expand Down Expand Up @@ -32,4 +32,30 @@ Assuming you've already finished [those steps in the main README](../../README.m

5. Create a Firebase firestore database

2. Run `yarn dev` and checkout `http://localhost:3000` URL.
- Don't forget to set security `Rules`:

```
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {
// Deny all access by default
match /{document=**} {
allow read, write: if false;
}

// Match for users collection
match /users/{uid} {
allow read: if request.auth != null && request.auth.uid == uid;
}

// Match for passkeys collection
match /passkeys/{passkeyId} {
allow read: if request.auth != null && resource.data.userId == request.auth.uid;
}
}
}
```

2. Run `yarn dev` in **root repository** and checkout `http://localhost:3000` URL.
3. Hey mate, welcome to the WebAuthn world. 🙌
48 changes: 5 additions & 43 deletions examples/webauthn-default/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { NextConfig } from 'next';
import { withSentryConfig } from '@sentry/nextjs';
import { config } from 'dotenv';
import type { dependencies } from 'package.json';

import { withDefinedSentryConfig } from '@workspace/sentry/next-config';

if (process.env.NODE_ENV === 'development') {
config({
path: '.env.local',
});
config({ path: '.env.local' });
config({ path: '../../.env' });
}

type Dependency = keyof typeof dependencies;
Expand All @@ -28,42 +28,4 @@ const nextConfig: NextConfig = {
// ensure that your source maps include changes from all other Webpack plugins
export default process.env.NEXT_PUBLIC_DEV_SENTRY_DISABLED === 'true'
? nextConfig
: withSentryConfig(nextConfig, {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options

org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,

// Only print logs for uploading source maps in CI
silent: !process.env.CI,

// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,

// Automatically annotate React components to show their full name in breadcrumbs and session replay
reactComponentAnnotation: {
enabled: true,
},

// Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
// This can increase your server load as well as your hosting bill.
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
// side errors will fail.
// tunnelRoute: "/monitoring",

// Hides source maps from generated client bundles
hideSourceMaps: true,

// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,

// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: true,
});
: withDefinedSentryConfig(nextConfig);
Loading