diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..547fbf1 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1 @@ +FROM mcr.microsoft.com/devcontainers/javascript-node:22-bookworm diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..bc63d70 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +{ + "name": "Node.js", + "dockerComposeFile": [ + "docker-compose.yaml" + ], + "service": "dashboard", + "workspaceFolder": "/workspaces", + "init": true, + "shutdownAction": "stopCompose", + "customizations": { + "vscode": { + "extensions": [ + "ms-azuretools.vscode-docker" + ] + }, + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + } + }, + "forwardPorts": [ + 4433, + 4434, + 4436, + 4437, + 4444, + 4445, + 5555, + 5432 + ], + "postCreateCommand": "npm install -g bun" +} \ No newline at end of file diff --git a/.devcontainer/docker-compose.yaml b/.devcontainer/docker-compose.yaml new file mode 100644 index 0000000..9c16a3d --- /dev/null +++ b/.devcontainer/docker-compose.yaml @@ -0,0 +1,109 @@ +services: + dashboard: + build: + context: ../dashboard + dockerfile: ../.devcontainer/Dockerfile + + volumes: + - ../:/workspaces:cached + + # environment: + + command: sleep infinity + network_mode: service:ory-postgres + + ory-kratos-migrate: + container_name: ory-kratos-migrate + image: oryd/kratos:v1.3.1 + restart: on-failure + volumes: + - ./ory/kratos:/etc/config/kratos + - ory-kratos-data:/home/ory + - ory-kratos-data:/var/lib/sqlite + command: -c /etc/config/kratos/kratos.yaml migrate sql -e --yes + depends_on: + ory-postgres: + condition: service_healthy + network_mode: service:ory-postgres + + ory-kratos: + container_name: ory-kratos + image: oryd/kratos:v1.3.1 + restart: unless-stopped + # ports: + # - 127.0.0.1:4433:4433 # public + # - 127.0.0.1:4434:4434 # admin + volumes: + - ./ory/kratos:/etc/config/kratos + - ory-kratos-data:/home/ory + - ory-kratos-data:/var/lib/sqlite + command: serve -c /etc/config/kratos/kratos.yaml --dev --watch-courier + depends_on: + ory-kratos-migrate: + condition: service_completed_successfully + network_mode: service:ory-postgres + + ory-hydra-migrate: + container_name: ory-hydra-migrate + image: oryd/hydra:v2.2.0 + restart: on-failure + volumes: + - ./ory/hydra:/etc/config/hydra + - ory-hydra-data:/home/ory + - ory-hydra-data:/var/lib/sqlite + command: migrate -c /etc/config/hydra/hydra.yaml sql -e --yes + depends_on: + ory-postgres: + condition: service_healthy + network_mode: service:ory-postgres + + ory-hydra: + container_name: ory-hydra + image: oryd/hydra:v2.2.0 + restart: unless-stopped + # ports: + # - 127.0.0.1:4444:4444 # public + # - 127.0.0.1:4445:4445 # admin + # - 127.0.0.1:5555:5555 # Port for hydra token user + volumes: + - ./ory/hydra:/etc/config/hydra + - ory-hydra-data:/home/ory + - ory-hydra-data:/var/lib/sqlite + command: serve -c /etc/config/hydra/hydra.yaml all --dev + depends_on: + ory-hydra-migrate: + condition: service_completed_successfully + network_mode: service:ory-postgres + + ory-mailslurper: + container_name: ory-mailslurper + image: oryd/mailslurper:latest-smtps + restart: unless-stopped + # ports: + # - 127.0.0.1:4436:4436 + # - 127.0.0.1:4437:4437 + network_mode: service:ory-postgres + + ory-postgres: + container_name: ory-postgres + image: postgres:15.2 + restart: unless-stopped + healthcheck: + test: [ "CMD-SHELL", "pg_isready" ] + interval: 10s + timeout: 5s + retries: 5 + # ports: + # - 127.0.0.1:5432:5432 + environment: + POSTGRES_DB: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + volumes: + - ory-postgres-data:/var/lib/postgresql/data + - ./postgres:/docker-entrypoint-initdb.d/ + +volumes: + ory-kratos-data: + ory-hydra-data: + ory-postgres-data: diff --git a/.devcontainer/ory/hydra/hydra.yaml b/.devcontainer/ory/hydra/hydra.yaml new file mode 100644 index 0000000..f6b16e3 --- /dev/null +++ b/.devcontainer/ory/hydra/hydra.yaml @@ -0,0 +1,88 @@ +# +# Documentation: https://www.ory.sh/docs/hydra/reference/configuration +# Configuration UI: https://www.ory.sh/docs/hydra/reference/configuration-editor +# + +# +# Configure the Hydra logging +# +log: + level: info + format: text + leak_sensitive_values: true + + +# +# Configure the datasource. Alternative for development purposes is 'memory' (not persistent!) +# +dsn: postgres://postgres:postgres@ory-postgres:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4 + + +# +# Configure the base URLs for the public and admin API. +# The public URL is used in emails for verification links. +# +serve: + + public: + cors: + enabled: true + debug: true + allowed_origins: + - http://localhost:3000 + + admin: + cors: + enabled: true + debug: true + allowed_origins: + - http://localhost:3000 + + cookies: + domain: http://localhost + same_site_mode: Lax + secure: false + paths: + session: / + names: + consent_csrf: ory_hydra_consent_csrf + session: ory_hydra_session + login_csrf: ory_hydra_login_csrf + + +urls: + + consent: http://localhost:3000/flow/consent + login: http://localhost:3000/flow/login + logout: http://localhost:3000/flow/logout + post_logout_redirect: http://localhost:3000 + + identity_provider: + url: http://kratos:4434 + + self: + public: http://localhost:4444 + admin: http://localhost:4445 + issuer: http://localhost:4444 + + +# +# Configure secrets and key rotation. +# Documentation: https://www.ory.sh/docs/hydra/self-hosted/secrets-key-rotation +# +secrets: + system: + - youReallyNeedToChangeThis + + +# +# Configure the OAuth2 clients. +# Documentation: https://www.ory.sh/docs/hydra/next/clients +# +oidc: + subject_identifiers: + supported_types: + - pairwise + - public + pairwise: + salt: youReallyNeedToChangeThis diff --git a/.devcontainer/ory/kratos/discord.data-mapper.jsonnet b/.devcontainer/ory/kratos/discord.data-mapper.jsonnet new file mode 100644 index 0000000..b9d6f35 --- /dev/null +++ b/.devcontainer/ory/kratos/discord.data-mapper.jsonnet @@ -0,0 +1,13 @@ + +local claims = std.extVar('claims'); + +{ + identity: { + traits: { + [if 'email' in claims && claims.email_verified then 'email' else null]: claims.email, + [if 'nickname' in claims then 'username' else null]: claims.nickname, + [if 'nickname' in claims then 'name' else null]: claims.nickname, + }, + metadata_public: claims, + }, +} diff --git a/.devcontainer/ory/kratos/identity.schema.json b/.devcontainer/ory/kratos/identity.schema.json new file mode 100644 index 0000000..b937fc1 --- /dev/null +++ b/.devcontainer/ory/kratos/identity.schema.json @@ -0,0 +1,43 @@ +{ + "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "User", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email", + "title": "Email", + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + }, + "webauthn": { + "identifier": true + } + }, + "recovery": { + "via": "email" + }, + "verification": { + "via": "email" + } + } + }, + "name": { + "type": "string", + "title": "Name" + } + }, + "required": [ + "email", + "name" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/.devcontainer/ory/kratos/kratos.yaml b/.devcontainer/ory/kratos/kratos.yaml new file mode 100644 index 0000000..0913a29 --- /dev/null +++ b/.devcontainer/ory/kratos/kratos.yaml @@ -0,0 +1,137 @@ +# +# Documentation: https://www.ory.sh/docs/kratos/reference/configuration +# Configuration UI: https://www.ory.sh/docs/kratos/reference/configuration-editor +# + +# +# Configure the Kratos logging +# +log: + level: info + format: text + leak_sensitive_values: true + +# +# Configure the datasource. Alternative for development purposes is 'memory' (not persistent!) +# +dsn: postgres://postgres:postgres@ory-postgres:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4 + +# +# Configure the base URLs for the public and admin API. +# The public URL is used in emails for verification links. +# +serve: + public: + base_url: http://localhost:4433 + cors: + enabled: true + allowed_origins: + - http://localhost:3000 + - http://localhost:4000 + admin: + base_url: http://localhost:4434 + +# +# Configure the session cookie. +# +cookies: + domain: http://localhost + path: / + same_site: Lax + +# +# Configure the self-service flows.session. +# Probably most interesting are ui urls, return urls and hooks.session. +# You can also activate authentication methods. +# +selfservice: + default_browser_return_url: http://localhost:3000 + allowed_return_urls: + - http://localhost:3000 + - http://localhost:4000 + + methods: + password: + enabled: true + totp: + enabled: true + config: + issuer: ORY Template + lookup_secret: + enabled: true + + flows: + error: + ui_url: http://localhost:3000/flow/error + + settings: + required_aal: highest_available + ui_url: http://localhost:3000 + + recovery: + enabled: true + ui_url: http://localhost:3000/flow/recovery + + verification: + enabled: true + ui_url: http://localhost:3000/flow/verification + + login: + ui_url: http://localhost:3000/flow/login + lifespan: 10m + after: + hooks: + - hook: require_verified_address + + registration: + lifespan: 10m + ui_url: http://localhost:3000/flow/registration + # after: + # default_browser_return_url: http://localhost:3000 + # password: + # hooks: + # - hook: session # automatically sign-in after registration + +# +# Configure connection to hydra for oauth2 and oidc. +# If set, the login and registration flows will handle the Ory OAuth 2.0 & OpenID `login_challenge` query parameter to serve as an OpenID Connect Provider. +# +oauth2_provider: + override_return_to: false + url: http://ory-hydra:4445 + +# +# Configure secrets and key rotation. +# Documentation: https://www.ory.sh/docs/kratos/guides/secret-key-rotation +# +secrets: + cookie: + - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE + cipher: + - 32-LONG-SECRET-NOT-SECURE-AT-ALL + +ciphers: + algorithm: xchacha20-poly1305 + +hashers: + algorithm: bcrypt + bcrypt: + cost: 8 + +# +# The delivered identity schema shows how to use the schema system. +# Documentation: https://www.ory.sh/docs/kratos/manage-identities/identity-schema +# +identity: + default_schema_id: default + schemas: + - id: default + url: file:///etc/config/kratos/identity.schema.json + +# +# Configure the mailing service. +# Documentation: https://www.ory.sh/docs/kratos/self-hosted/mail-courier-selfhosted +# +courier: + smtp: + connection_uri: smtps://test:test@ory-mailslurper:1025/?skip_ssl_verify=true diff --git a/.devcontainer/ory/kratos/twitch.data-mapper.jsonnet b/.devcontainer/ory/kratos/twitch.data-mapper.jsonnet new file mode 100644 index 0000000..6dd93b0 --- /dev/null +++ b/.devcontainer/ory/kratos/twitch.data-mapper.jsonnet @@ -0,0 +1,11 @@ + +local claims = std.extVar('claims'); + +{ + identity: { + traits: { + [if 'email' in claims && claims.email_verified then 'email' else null]: claims.email + }, + metadata_public: claims, + }, +} \ No newline at end of file diff --git a/.devcontainer/postgres/init.sql b/.devcontainer/postgres/init.sql new file mode 100644 index 0000000..1e2b2ed --- /dev/null +++ b/.devcontainer/postgres/init.sql @@ -0,0 +1,5 @@ +CREATE DATABASE kratos; +GRANT ALL PRIVILEGES ON DATABASE kratos TO postgres; + +CREATE DATABASE hydra; +GRANT ALL PRIVILEGES ON DATABASE hydra TO postgres; diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f33a02c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for more information: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +# https://containers.dev/guide/dependabot + +version: 2 +updates: + - package-ecosystem: "devcontainers" + directory: "/" + schedule: + interval: weekly