Skip to content

Commit

Permalink
feat(#5): wire up auth0 on frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
meatwallace committed Apr 30, 2024
1 parent b105a89 commit 9a72972
Show file tree
Hide file tree
Showing 246 changed files with 4,086 additions and 1,111 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
with:
fetch-depth: 0

- name: Setup Dotenv
run: |
echo "${{secrets.DOTENV_APP_WEB_DEV }}" > projects/app-web/.env.development.local
echo "${{secrets.DOTENV_APP_WEB_E2E }}" > projects/app-web-e2e/.env
echo "${{secrets.DOTENV_DB_POSTGRES }}" > projects/db-postgres/.env.production
- name: Setup Node
uses: actions/setup-node@v3
with:
Expand Down Expand Up @@ -76,9 +82,7 @@ jobs:

- name: Deploy Postgres Migrations
if: ${{ github.ref_name == 'main' && contains(steps.record-affected-projects.outputs.affected-projects, 'db-postgres') }}
run: |
echo "${{secrets.DOTENV_DB_POSTGRES }}" > projects/db-postgres/.env.production
yarn postgres:migrations-run:prod
run: yarn postgres:migrations-run:prod

- name: Deploy API Service
if: ${{ github.ref_name == 'main' && contains(steps.record-affected-projects.outputs.affected-projects, 'service-api') }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ testem.log
# System Files
.DS_Store
Thumbs.db
*Zone.Identifier

# caches
.cache
Expand All @@ -47,3 +48,5 @@ Thumbs.db
# secrets
projects/db-postgres/.env.production
projects/service-*/.env.production
projects/app-web-e2e/.env
**/.env*.local
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
yarn dlx lint-staged --concurrent false --relative
yarn dlx lint-staged --concurrent false --relative --allow-empty
1,300 changes: 830 additions & 470 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/cuid-npm-3.0.0-66e229f427-e1cac04b8d.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/msw-npm-1.3.3-7cd6e8f445-0c63b282a5.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified .yarn/install-state.gz
Binary file not shown.
61 changes: 61 additions & 0 deletions .yarn/patches/mock-jwks-npm-3.1.0-131e3bbc29.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
diff --git a/build/index.d.ts b/build/index.d.ts
index 575dc0e00c51ac7dac66c4e4885c2414ee98fa91..50717f586aba777a4239b726a90347d9c3dcea45 100644
--- a/build/index.d.ts
+++ b/build/index.d.ts
@@ -1,5 +1,8 @@
import { JwtPayload } from 'jsonwebtoken';
+import { HttpHandler } from 'msw';
+
declare const createJWKSMock: (jwksBase: string, jwksPath?: string) => {
+ handler: HttpHandler
start: () => void;
stop: () => void;
kid: () => string;
diff --git a/build/index.js b/build/index.js
index 289a2dac6cd569eef5dbc9329914a7517b442829..bfe7abde0ad358d21b707cc2fa69f721b02b8955 100644
--- a/build/index.js
+++ b/build/index.js
@@ -1,13 +1,20 @@
import { createJWKS, createKeyPair, signJwt } from './tools.js';
import { setupServer } from 'msw/node';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
+
const createJWKSMock = (jwksBase, jwksPath = '/.well-known/jwks.json') => {
const keypair = createKeyPair();
const JWKS = createJWKS({
...keypair,
jwksOrigin: jwksBase,
});
- const server = setupServer(rest.get(new URL(jwksPath, jwksBase).href, (_, res, ctx) => res(ctx.status(200), ctx.json(JWKS))));
+
+ // we patch & expose the actual msw handler so we can plug it into our own server rather than
+ // creating a conflicting instance. we also bump the msw version to match our own to avoid any
+ // compatibility issues.
+ const handler = http.get(new URL(jwksPath, jwksBase).href, () => HttpResponse.json(JWKS));
+
+ const server = setupServer(handler);
const kid = () => JWKS.keys[0].kid;
const start = () => {
server.listen({ onUnhandledRequest: 'bypass' });
@@ -17,6 +24,7 @@ const createJWKSMock = (jwksBase, jwksPath = '/.well-known/jwks.json') => {
};
const token = (token = {}) => signJwt(keypair.privateKey, token, kid());
return {
+ handler,
start,
stop,
kid,
diff --git a/package.json b/package.json
index e5a5c2fc6b6b5dfec0c88bbf2adf4a88ba33e18b..412355319913b9b7a3743974c47d29fb834c9a93 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,7 @@
"dependencies": {
"base64-url": "^2.3.3",
"jsonwebtoken": "^9.0.0",
- "msw": "^1.2.2",
+ "msw": "2.2.14",
"node-forge": "^1.3.1",
"node-rsa": "^1.1.1"
},
13 changes: 6 additions & 7 deletions codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ const config: CodegenConfig = {
plugins: ['schema-ast'],
},
},
// TODO: enable when introducing graphql-scalars
// config: {
// scalars: {
// UUID: 'string',
// DateTime: 'Date',
// },
// },
config: {
scalars: {
Date: 'Date',
DateTime: 'Date',
},
},
};

export default config;
7 changes: 7 additions & 0 deletions eslint.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ module.exports = tseslint.config(
//
},
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
ignoreRestSiblings: true,
},
],

'unicorn/no-null': 'off',
'unicorn/prevent-abbreviations': 'off',
},
Expand Down
1 change: 1 addition & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export default {
(files) => `yarn nx affected:lint --files=${files.join(',')}`,
(files) => `yarn nx format:write --files=${files.join(',')}`,
],
'projects/lib-postgres-schema/**/*.ts': ['yarn postgres:migrations-generate'],
'**/*.graphql': ['yarn nx format:write'],
};
42 changes: 32 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
"private": true,
"type": "module",
"scripts": {
"clean": "rm -rf '.nx/' 'tmp/' '**/.cache' '**/build/' '**/node_modules/' '**/dist/' '**/*.timestamp*.mjs'",
"build": "nx run-many -t build",
"lint": "nx run-many -t lint",
"test": "nx run-many -t test",
"typecheck": "nx run-many -t typecheck",
"e2e": "nx run-many -t e2e",
"codegen:graphql": "graphql-codegen",
"codegen:graphql": "TS_NODE_PROJECT=tsconfig.base.json graphql-codegen --require tsconfig-paths/register",
"postgres:start": "docker-compose -f ./docker-compose.yml up -d",
"postgres:migrations-generate": "nx migrations-generate db-postgres",
"postgres:migrations-run:dev": "nx migrations-run-dev db-postgres",
Expand Down Expand Up @@ -45,6 +46,7 @@
"@graphql-codegen/schema-ast": "4.0.2",
"@graphql-tools/executor-http": "1.0.9",
"@graphql-typed-document-node/core": "3.2.0",
"@mswjs/data": "0.16.1",
"@nx/devkit": "18.3.3",
"@nx/esbuild": "18.3.3",
"@nx/eslint": "18.3.3",
Expand All @@ -64,20 +66,23 @@
"@swc/core": "1.4.13",
"@swc/helpers": "0.5.8",
"@testcontainers/postgresql": "10.9.0",
"@testing-library/dom": "10.0.0",
"@testing-library/jest-dom": "6.4.2",
"@testing-library/react": "14.3.0",
"@testing-library/user-event": "14.5.2",
"@types/jsonwebtoken": "9.0.6",
"@types/node": "20.12.7",
"@types/react": "18.2.75",
"@types/react-dom": "18.2.24",
"@types/react-is": "18.2.4",
"@types/styled-components": "5.1.34",
"@typescript-eslint/eslint-plugin": "7.6.0",
"@typescript-eslint/parser": "7.6.0",
"@typescript-eslint/utils": "7.7.1",
"@vanilla-extract/vite-plugin": "4.0.7",
"@vitejs/plugin-react": "4.2.1",
"@vitest/coverage-v8": "1.5.1",
"@vitest/ui": "1.5.1",
"@vitest/coverage-v8": "1.5.2",
"@vitest/expect": "1.5.2",
"@vitest/ui": "1.5.2",
"drizzle-kit": "0.20.17",
"esbuild": "0.20.2",
"eslint": "9.0.0",
Expand All @@ -88,34 +93,45 @@
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-unicorn": "52.0.0",
"graphql-transform-scalars": "1.2.1",
"happy-dom": "14.7.1",
"husky": "9.0.11",
"jest-extended": "4.0.2",
"jwt-decode": "4.0.0",
"lint-staged": "15.2.2",
"mock-jwks": "3.1.0",
"mock-jwks": "patch:mock-jwks@npm%3A3.1.0#~/.yarn/patches/mock-jwks-npm-3.1.0-131e3bbc29.patch",
"msw": "2.2.14",
"node-mocks-http": "1.14.1",
"nx": "18.3.3",
"playwright": "1.43.0",
"prettier": "3.2.5",
"remix-flat-routes": "0.6.4",
"tsconfig-paths": "4.2.0",
"tslib": "2.6.2",
"tsx": "4.7.3",
"type-fest": "4.17.0",
"typescript": "5.4.5",
"typescript-eslint": "7.6.0",
"vite": "5.2.10",
"vitest": "1.5.1"
"vitest": "1.5.2"
},
"dependencies": {
"@hono/node-server": "1.10.0",
"@paralleldrive/cuid2": "2.2.2",
"@pothos/core": "3.41.1",
"@remix-run/node": "2.9.1",
"@remix-run/react": "2.9.1",
"@remix-run/serve": "2.9.1",
"@remix-run/server-runtime": "2.9.1",
"@vanilla-extract/css": "1.14.2",
"@vanilla-extract/sprinkles": "1.6.1",
"auth0": "4.3.1",
"cuid": "3.0.0",
"drizzle-orm": "0.30.9",
"envalid": "8.0.0",
"got": "14.2.1",
"graphql": "16.8.1",
"graphql-request": "6.1.0",
"graphql-scalars": "1.23.0",
"graphql-yoga": "5.3.0",
"hono": "4.2.4",
"isbot": "4",
Expand All @@ -126,9 +142,12 @@
"react-dom": "18.2.0",
"react-is": "18.2.0",
"react-router-dom": "6.22.3",
"remix-auth": "3.6.0",
"remix-auth-auth0": "1.10.0",
"remix-auth-oauth2": "1.11.2",
"remix-hono": "0.0.16",
"styled-components": "6.1.8",
"tiny-invariant": "1.3.3"
"tiny-invariant": "1.3.3",
"uuid": "9.0.1"
},
"packageManager": "yarn@4.1.1",
"dockerfile": {
Expand All @@ -137,5 +156,8 @@
},
"workspaces": [
"projects/*"
]
],
"resolutions": {
"msw@npm:^1.2.2": "2.2.14"
}
}
20 changes: 15 additions & 5 deletions projects/app-web-e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import { defineConfig, devices } from '@playwright/test';
import { nxE2EPreset } from '@nx/playwright/preset';
import { workspaceRoot } from '@nx/devkit';
Expand All @@ -9,17 +10,26 @@ const __filename = fileURLToPath(import.meta.url);
// For CI, you may want to set BASE_URL to the deployed application.
const baseURL = process.env['BASE_URL'] || 'http://localhost:4000';

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
// having a million issues trying to use __dirname to establish a reliable path
// so it's easier to do this to handle the case when this file gets parsed for
// building our nx graph
const projectRoot = process.cwd().includes('app-web-e2e')
? process.cwd()
: `${process.cwd()}/projects/app-web-e2e`;

const dotEnvFile = path.join(projectRoot, '.env');

process.loadEnvFile(dotEnvFile);

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
...nxE2EPreset(__filename, { testDir: './src' }),
timeout: 60 * 1000,
expect: {
timeout: 10 * 1000,
},
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
baseURL,
Expand Down
13 changes: 13 additions & 0 deletions projects/app-web-e2e/src/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { cleanEnv, str } from 'envalid';
import { Env } from './types';

export const env: Env = cleanEnv(process.env, {
NODE_ENV: str({ choices: ['development', 'test', 'e2e', 'production'] }),
LOGGING: str({
choices: ['debug', 'info', 'warn', 'error'],
default: 'info',
}),

TEST_USER_EMAIL: str(),
TEST_USER_PASSWORD: str(),
});
7 changes: 0 additions & 7 deletions projects/app-web-e2e/src/example.test.ts

This file was deleted.

18 changes: 18 additions & 0 deletions projects/app-web-e2e/src/sign-up.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { test, expect } from '@playwright/test';
import { env } from './env';

test('it signs the user in and welcomes them', async ({ page }) => {
await page.goto('/');

await page.getByRole('button', { name: 'Log in' }).click();

await expect(page).toHaveURL(/chrononomicon\.us\.auth0\.com\/u\/login/);

await page.getByLabel('Email address').fill(env.TEST_USER_EMAIL);
await page.getByLabel('Password').fill(env.TEST_USER_PASSWORD);
await page.getByRole('button', { name: 'Continue', exact: true }).click();

await expect(page).toHaveURL(/localhost:4000/);

await expect(page.getByText('Hello, Test User')).toBeVisible();
});
11 changes: 11 additions & 0 deletions projects/app-web-e2e/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type Env = {
LOGGING: 'debug' | 'info' | 'warn' | 'error';
NODE_ENV: 'development' | 'test' | 'e2e' | 'production';

TEST_USER_EMAIL: string;
TEST_USER_PASSWORD: string;

// utils
isProduction: boolean;
isDevelopment: boolean;
};
10 changes: 4 additions & 6 deletions projects/app-web-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"outDir": "../../dist/out-tsc",
"module": "esnext",
"sourceMap": false
"module": "ESNext",
"types": ["node"],
"sourceMap": false,
"esModuleInterop": true
},
"include": [
"**/*.ts",
"**/*.js",
"playwright.config.ts",
"src/**/*.test.ts",
"src/**/*.test.js",
"src/**/*.d.ts"
]
}
11 changes: 10 additions & 1 deletion projects/app-web/.env.development
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
VITE_DOMAIN=localhost
VITE_API_URL=http://localhost:3000/graphql
VITE_ENABLE_MSW=true

VITE_AUTH0_AUDIENCE="http://localhost:3000/"
VITE_AUTH0_CALLBACK_URL="http://localhost:4000/auth/callback"
VITE_AUTH0_CLIENT_ID="F7PgBpbgFpgNmkXdlbDIiAnugC0Lggb0"
VITE_AUTH0_DOMAIN="chrononomicon.us.auth0.com"
VITE_AUTH0_LOGOUT_URL="https://chrononomicon.us.auth0.com/v2/logout"
VITE_AUTH0_RETURN_URL="http://localhost:4000"

VITE_ENABLE_MSW=false
Loading

0 comments on commit 9a72972

Please sign in to comment.