Merge branch 'main' into passkey-registration

This commit is contained in:
Max Peintner
2023-06-26 14:47:40 +02:00
30 changed files with 1309 additions and 116 deletions

View File

@@ -0,0 +1 @@
ZITADEL_API_URL=http://localhost:22222

View File

@@ -1,16 +1,19 @@
import type { Config } from "@jest/types";
import { pathsToModuleNameMapper } from "ts-jest";
import { compilerOptions } from "./tsconfig.json";
import { compilerOptions } from "../tsconfig.json";
// We make these type imports explicit, so IDEs with their own typescript engine understand them, too.
import type {} from "@testing-library/jest-dom";
export default async (): Promise<Config.InitialOptions> => {
return {
preset: "ts-jest",
transform: {
"^.+\\.tsx?$": ["ts-jest", { tsconfig: "./__test__/tsconfig.json" }],
"^.+\\.tsx?$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.json" }],
},
setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>/",
prefix: "<rootDir>/../",
}),
testEnvironment: "jsdom",
testRegex: "/__test__/.*\\.test\\.tsx?$",

2
apps/login/cypress/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
screenshots
videos

View File

@@ -0,0 +1,12 @@
import { defineConfig } from "cypress";
export default defineConfig({
reporter: "list",
e2e: {
baseUrl: "http://localhost:3000",
specPattern: "cypress/integration/**/*.cy.{js,jsx,ts,tsx}",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,21 @@
import { addStub, removeStub } from "../support/mock";
describe("/verify", () => {
it("redirects after successful email verification", () => {
removeStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
addStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
cy.visit("/verify?userID=123&code=abc&submit=true");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/username");
});
it("shows an error if validation failed", () => {
removeStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
addStub("zitadel.user.v2alpha.UserService", "VerifyEmail", {
code: 3,
error: "error validating code",
});
// TODO: Avoid uncaught exception in application
cy.once("uncaught:exception", () => false);
cy.visit("/verify?userID=123&code=abc&submit=true");
cy.contains("error validating code");
});
});

View File

@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./commands";
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@@ -0,0 +1,26 @@
export function removeStub(service: string, method: string) {
return cy.request({
url: "http://localhost:22220/v1/stubs",
method: "DELETE",
qs: {
service: service,
method: method,
},
});
}
export function addStub(service: string, method: string, out?: any) {
return cy.request({
url: "http://localhost:22220/v1/stubs",
method: "POST",
body: {
stubs: [
{
service: service,
method: method,
out: out,
},
],
},
});
}

View File

@@ -0,0 +1,9 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}

View File

@@ -0,0 +1,20 @@
FROM bufbuild/buf:1.21.0 as protos
RUN buf export https://github.com/envoyproxy/protoc-gen-validate.git --path validate --output /proto
RUN buf export https://github.com/grpc-ecosystem/grpc-gateway.git --path protoc-gen-openapiv2 --output /proto
RUN buf export https://github.com/googleapis/googleapis.git --path google/api/annotations.proto --path google/api/http.proto --path google/api/field_behavior.proto --output /proto
RUN buf export https://github.com/zitadel/zitadel.git --path ./proto/zitadel --output /proto
FROM scratch AS config
COPY mocked-services.cfg .
COPY initial-stubs initial-stubs
COPY --from=protos /proto .
FROM golang:1.20.5-alpine3.18 as grpc-mock
RUN go install github.com/eliobischof/grpc-mock/cmd/grpc-mock@01b09f60db1b501178af59bed03b2c22661df48c
COPY --from=config / .
ENTRYPOINT [ "sh", "-c", "grpc-mock -v 1 -proto $(tr '\n' ',' < ./mocked-services.cfg) -stub-dir ./initial-stubs" ]

View File

@@ -0,0 +1,17 @@
[
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetBrandingSettings",
"out": {}
},
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetLegalAndSupportSettings",
"out": {}
},
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetPasswordComplexitySettings",
"out": {}
}
]

View File

@@ -0,0 +1,6 @@
zitadel/user/v2alpha/user_service.proto
zitadel/session/v2alpha/session_service.proto
zitadel/settings/v2alpha/settings_service.proto
zitadel/management.proto
zitadel/auth.proto
zitadel/admin.proto

View File

@@ -9,7 +9,7 @@ const nextConfig = {
remotePatterns: [
{
protocol: "https",
hostname: process.env.ZITADEL_API_URL.replace("https://", ""),
hostname: process.env.ZITADEL_API_URL?.replace("https://", "") || "",
port: "",
pathname: "/**",
},

View File

@@ -3,15 +3,27 @@
"private": true,
"scripts": {
"dev": "next dev",
"test": "jest",
"test:watch": "jest --watch",
"test": "concurrently --timings --kill-others-on-fail 'npm:test:unit' 'npm:test:integration'",
"test:watch": "concurrently --kill-others 'npm:test:unit:watch' 'npm:test:integration:watch'",
"test:unit": "jest --config ./__test__/jest.config.ts",
"test:unit:watch": "pnpm test:unit --watch",
"test:integration": "pnpm mock:build && concurrently --names 'mock,test' --success command-test --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test start http://localhost:3000 \"test:integration:run\"'",
"test:integration:watch": "concurrently --names 'mock,test' --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test dev http://localhost:3000 \"pnpm nodemon -e js,jsx,ts,tsx,css,scss --ignore \\\"__test__/**\\\" --exec \\\"pnpm test:integration:run\\\"\"'",
"test:integration:run": "cypress run --config-file ./cypress/cypress.config.ts --quiet",
"test:integration:open": "cypress open --config-file ./cypress/cypress.config.ts",
"mock": "pnpm mock:build && pnpm mock:run",
"mock:run": "pnpm mock:stop && docker run --rm --name zitadel-mock-grpc-server --publish 22220:22220 --publish 22222:22222 zitadel-mock-grpc-server",
"mock:build": "DOCKER_BUILDKIT=1 docker build --tag zitadel-mock-grpc-server ./mock",
"mock:build:nocache": "pnpm mock:build --no-cache",
"mock:stop": "docker rm --force zitadel-mock-grpc-server 2>/dev/null || true",
"mock:destroy": "docker rmi --force zitadel-mock-grpc-server 2>/dev/null || true",
"lint": "next lint && prettier --check .",
"lint:fix": "prettier --write .",
"lint-staged": "lint-staged",
"build": "next build",
"prestart": "build",
"prestart": "pnpm build",
"start": "next start",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
"clean": "pnpm mock:destroy && rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"git": {
"pre-commit": "lint-staged"
@@ -55,15 +67,21 @@
"@vercel/git-hooks": "1.0.0",
"@zitadel/tsconfig": "workspace:*",
"autoprefixer": "10.4.13",
"concurrently": "^8.1.0",
"cypress": "^12.14.0",
"del-cli": "5.0.0",
"env-cmd": "^10.1.0",
"eslint-config-zitadel": "workspace:*",
"grpc-tools": "1.11.3",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"jest-silent-reporter": "^0.5.0",
"lint-staged": "13.0.3",
"make-dir-cli": "3.0.0",
"nodemon": "^2.0.22",
"postcss": "8.4.21",
"prettier-plugin-tailwindcss": "0.1.13",
"start-server-and-test": "^2.0.0",
"tailwindcss": "3.2.4",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",

21
apps/login/turbo.json Normal file
View File

@@ -0,0 +1,21 @@
{
"extends": ["//"],
"pipeline": {
"build": {
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"dependsOn": ["^build"]
},
"test": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
},
"test:integration": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
},
"test:unit": {
"dependsOn": ["@zitadel/server#build"]
},
"test:watch": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
}
}
}