mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 10:45:19 +00:00
Merge branch 'main' into passkey-registration
This commit is contained in:
1
apps/login/.env.integration
Normal file
1
apps/login/.env.integration
Normal file
@@ -0,0 +1 @@
|
||||
ZITADEL_API_URL=http://localhost:22222
|
||||
@@ -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
2
apps/login/cypress/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
screenshots
|
||||
videos
|
||||
12
apps/login/cypress/cypress.config.ts
Normal file
12
apps/login/cypress/cypress.config.ts
Normal 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
|
||||
},
|
||||
},
|
||||
});
|
||||
5
apps/login/cypress/fixtures/example.json
Normal file
5
apps/login/cypress/fixtures/example.json
Normal 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"
|
||||
}
|
||||
21
apps/login/cypress/integration/verify.cy.ts
Normal file
21
apps/login/cypress/integration/verify.cy.ts
Normal 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");
|
||||
});
|
||||
});
|
||||
37
apps/login/cypress/support/commands.ts
Normal file
37
apps/login/cypress/support/commands.ts
Normal 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>
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
20
apps/login/cypress/support/e2e.ts
Normal file
20
apps/login/cypress/support/e2e.ts
Normal 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')
|
||||
26
apps/login/cypress/support/mock.ts
Normal file
26
apps/login/cypress/support/mock.ts
Normal 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,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
9
apps/login/cypress/tsconfig.json
Normal file
9
apps/login/cypress/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["es5", "dom"],
|
||||
"types": ["cypress", "node"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
20
apps/login/mock/Dockerfile
Normal file
20
apps/login/mock/Dockerfile
Normal 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" ]
|
||||
@@ -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": {}
|
||||
}
|
||||
]
|
||||
6
apps/login/mock/mocked-services.cfg
Normal file
6
apps/login/mock/mocked-services.cfg
Normal 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
|
||||
@@ -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: "/**",
|
||||
},
|
||||
|
||||
@@ -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
21
apps/login/turbo.json
Normal 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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user