Skip to content

Commit

Permalink
Production release (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
cermakjiri authored Nov 28, 2024
2 parents 3b142df + 0923cb1 commit fca5b02
Show file tree
Hide file tree
Showing 190 changed files with 4,187 additions and 1,400 deletions.
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

0 comments on commit fca5b02

Please sign in to comment.