Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[internal-1486] logto version upgrade and use logto schema #671

Merged
merged 22 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ebbe381
add logto schema, related to users, privileges to pg-mgmt
SantanM Feb 17, 2025
4d19a5d
remove public schema from logto-post-init
SantanM Feb 17, 2025
8266a61
upgrade logto v1.23.1
SantanM Feb 17, 2025
b73d1e4
use d2e custom logto base image
SantanM Feb 17, 2025
e2e5813
Merge branch 'develop' into SantanM/internal-1486_logto-schema
SantanM Feb 17, 2025
46517e9
fix logto tag name
SantanM Feb 17, 2025
32de1bf
Merge branch 'SantanM/internal-1486_logto-schema' of github.com:data2…
SantanM Feb 17, 2025
27204a5
docker-compose changes: add logto-seed service
SantanM Feb 18, 2025
66cc786
Merge branch 'develop' into SantanM/internal-1486_logto-schema
SantanM Feb 18, 2025
db39175
update Dockerfile for alp-logto build
SantanM Feb 18, 2025
591e266
Merge branch 'SantanM/internal-1486_logto-schema' of github.com:data2…
SantanM Feb 18, 2025
811d405
parameterize logto and remove sensitive info
SantanM Feb 19, 2025
1671abc
Merge branch 'develop' into SantanM/internal-1486_logto-schema
SantanM Feb 19, 2025
f2183cf
update logto-seed image
SantanM Feb 19, 2025
76be55f
add platform to logto-seed
SantanM Feb 19, 2025
e38bff4
log all services in http-tests
SantanM Feb 19, 2025
ffadfeb
log all services in http-tests
SantanM Feb 19, 2025
1edb5cf
revert and add logto-seed logs in gh action
SantanM Feb 19, 2025
5bf3e23
Merge branch 'develop' into SantanM/internal-1486_logto-schema
SantanM Feb 20, 2025
08ac1fe
fix pg_host in dc.yaml
SantanM Feb 20, 2025
e4deec6
Merge branch 'SantanM/internal-1486_logto-schema' of github.com:data2…
SantanM Feb 20, 2025
05c8dda
use correct password for logto_postgres
SantanM Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/docker-compose-up.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ jobs:
run: |
yarn ci:logs:minerva

- name: print logs for alp-logto-seed
if: ${{ always() || cancelled() || failure() }}
run: |
docker logs alp-logto-seed -t

- name: Clean Docker compose
if: always()
run: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/http-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ jobs:
if: ${{ always() || cancelled() || failure() }}
run: |
docker logs alp-logto-post-init-1 -t
- name: print logs for alp-logto-seed
if: ${{ always() || cancelled() || failure() }}
run: |
docker logs alp-logto-seed -t

- name: Remove Test DB
if: ${{ always() || cancelled() || failure() }}
Expand Down
1 change: 1 addition & 0 deletions deploy/caddy-config/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ https://*.alp.local:55555 {
# Logto api server
@logto {
path /index.*
path /assets/* # logto assets are moved to this path
path /api/*
path /oidc/*
path /sign-in
Expand Down
2 changes: 1 addition & 1 deletion docker-compose-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ services:
alp-logto:
build:
context: ./services/alp-logto
dockerfile: Dockerfile.local
dockerfile: Dockerfile

alp-minerva-pg-mgmt-init:
ports:
Expand Down
39 changes: 34 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ services:
"+cdw_config": {},
"+dataflow": {},
"+db_credentials_mgr": {},
"+logto": {},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A schema for logto tables

"+portal": {},
"+public": {},
"+qe_config": {},
Expand All @@ -476,7 +477,9 @@ services:
"reader": "${PG_WRITE_USER:-alp_pg_write_user}",
"readerPassword": "${PG_WRITE_PASSWORD}",
"writer": "${PG_WRITE_USER:-alp_pg_write_user}",
"writerPassword": "${PG_WRITE_PASSWORD}"
"writerPassword": "${PG_WRITE_PASSWORD}",
"logtoManager": "${PG_LOGTO_MANAGER:-logto_postgres}",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PG user that manages logto schema. It has the following privileges - USAGE, CREATE and GRANT (can further grant privileges to other pg users) privileges.

"logtoManagerPassword": "${PG__LOGTO_MANAGER_PASSWORD}"
}
}
POSTGRES_MANAGE_ROLES_USERS: ${POSTGRES_MANAGE_ROLES_USERS:-{}}
Expand Down Expand Up @@ -675,11 +678,11 @@ services:
priority: 20
environment:
ENV_TYPE: ${ENV_TYPE:-local}
PG__DB_NAME: logto
PG__DB_NAME: alp
PG__HOST: ${PG_HOST:-${PROJECT_NAME:-d2e}-minerva-postgres-1}
PG__PASSWORD: ${PG_SUPER_PASSWORD}
PG__PORT: ${PG_PORT:-5432}
PG__USER: ${PG_SUPER_USER:-postgres}
PG__USER: ${PG__LOGTO_MANAGE_USER:-logto_postgres}
PG__SSL: ${PG__SSL:-false}
# LOGTO__CUSTOM_JWT: '{"script": "/**\n* This function is called during the access token generation process to get custom claims for the JWT token.\n* Limit custom claims to under 50KB.\n*\n* @param {Object} payload - The input payload of the function.\n* @param {AccessTokenPayload} payload.token -The JWT token.\n* @param {Context} payload.context - Logto internal data that can be used to pass additional information\n* @param {EnvironmentVariables} [payload.environmentVariables] - The environment variables.\n*\n* @returns The custom claims.\n*/\n\n// @ts-ignore\nconst getCustomJwtClaims = async ({ token, context, environmentVariables, extra }) => {\n return { ...extra };\n}", "tokenSample": {"aud": "http://localhost:3000/api/test", "gty": "authorization_code", "jti": "f1d3d2d1-1f2d-3d4e-5d6f-7d8a9d0e1d2", "kind": "AccessToken", "scope": "read write", "grantId": "grant_123", "clientId": "my_app", "accountId": "uid_123"}, "contextSample": {"user": {"id": "123", "name": "Foo Bar", "roles": [], "avatar": "https://example.com/avatar.png", "profile": {}, "username": "foo", "customData": {}, "identities": {}, "hasPassword": false, "primaryEmail": "[email protected]", "primaryPhone": "+1234567890", "applicationId": "my-app", "organizations": [], "ssoIdentities": [], "organizationRoles": [], "mfaVerificationFactors": []}}}'
LOGTO__CLIENT_APPS: '[{"name":"alp-svc","description":"alp-svc","type":"MachineToMachine", "id": "${LOGTO__ALP_SVC__CLIENT_ID}", "secret": "${LOGTO__ALP_SVC__CLIENT_SECRET}"},{"name":"alp-data","description":"alp-data","type":"MachineToMachine", "id": "${LOGTO__ALP_DATA__CLIENT_ID}", "secret": "${LOGTO__ALP_DATA__CLIENT_SECRET}"},{"name":"alp-app","description":"alp-app","type":"Traditional", "id": "${LOGTO__ALP_APP__CLIENT_ID}", "secret": "${LOGTO__ALP_APP__CLIENT_SECRET}", "oidcClientMetadata":{"redirectUris":["https://${CADDY__ALP__PUBLIC_FQDN:-localhost}${PORT:+:${PORT:-443}}/portal/login-callback","https://localhost:4000/portal/login-callback","https://localhost:8081"],"postLogoutRedirectUris":["https://${CADDY__ALP__PUBLIC_FQDN:-localhost}${PORT:+:${PORT:-443}}/portal","https://localhost:4000/portal","https://localhost:8081"]},"customClientMetadata":{"corsAllowedOrigins":[],"refreshTokenTtlInDays":14,"alwaysIssueRefreshToken":true,"rotateRefreshToken":true}}]'
Expand All @@ -697,6 +700,8 @@ services:
depends_on:
alp-minerva-pg-mgmt-init:
condition: service_completed_successfully
alp-logto-seed:
condition: service_completed_successfully
healthcheck:
interval: 20s
retries: 30
Expand All @@ -708,6 +713,7 @@ services:
- logto.status
- http://localhost:3001/api/status
hostname: ${PROJECT_NAME:-d2e}-logto-1.${TLS__INTERNAL__DOMAIN:-alp.local}
platform: linux/amd64
image: ghcr.io/data2evidence/d2e-logto:${DOCKER_TAG_NAME:-develop}
logging:
options:
Expand All @@ -723,14 +729,14 @@ services:
entrypoint:
- sh
- -c
- npm run cli db seed -- --swe && npx @logto/cli db alteration deploy 1.18.0 && npm start
- npm start
Copy link
Contributor Author

@SantanM SantanM Feb 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see below alp-logto-seed

restart: ${DOCKER__RESTART_POLICY:-unless-stopped}
environment:
<<:
- *x-tls
ADMIN_DISABLE_LOCALHOST: ${LOGTO__DISABLE_ADMIN_CONSOLE:-false}
# ADMIN_ENDPOINT: http://${CADDY__ALP__PUBLIC_FQDN:-localhost}:3002 # Enable if need to access admin console
DB_URL: postgres://postgres:${PG_SUPER_PASSWORD}@${PROJECT_NAME:-d2e}-minerva-postgres-1:${PG_PORT:-5432}/logto
DB_URL: postgres://${PG__LOGTO_MANAGER_USER:-logto_postgres}:${PG__LOGTO_MANAGER_PASSWORD}@${PG_HOST}:${PG_PORT:-5432}/${PG_DB_NAME:-alp}
ENDPOINT: https://${CADDY__ALP__PUBLIC_FQDN:-localhost}${PORT:+:${PORT:-443}}
LOGTO_API_M2M_CLIENT_ID: ${LOGTO_API_M2M_CLIENT_ID}
LOGTO_API_M2M_CLIENT_SECRET: ${LOGTO_API_M2M_CLIENT_SECRET}
Expand All @@ -739,6 +745,29 @@ services:
PROJECT_NAME: ${PROJECT_NAME:-d2e}
PORT: 3001
TRUST_PROXY_HEADER: true
DATABASE_CONNECTION_TIMEOUT: 30000

alp-logto-seed:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate seeding and migration of logto schema to reduce the startup time of the container.

container_name: &c37 alp-logto-seed
image: ghcr.io/data2evidence/d2e-logto:${DOCKER_TAG_NAME:-develop}
platform: linux/amd64
entrypoint:
- sh
- -c
- npm run cli db seed -- --swe && npx @logto/cli db alteration rollback 1.22.0 && npx @logto/cli db alteration deploy 1.23.1
depends_on:
alp-minerva-postgres:
condition: service_healthy
alp-minerva-pg-mgmt-init:
condition: service_completed_successfully
networks:
alp:
priority: 20
environment:
DB_URL: postgres://${PG__LOGTO_MANAGER_USER:-logto_postgres}:${PG__LOGTO_MANAGER_PASSWORD}@${PG_HOST}:${PG_PORT:-5432}/${PG_DB_NAME:-alp}
logging:
options:
tag: *c37

alp-minerva-postgres:
container_name: &c17 ${PROJECT_NAME:-d2e}-minerva-postgres-1
Expand Down
1 change: 1 addition & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ MINIO__SECRET_KEY='${MINIO__SECRET_KEY}' # password
PG_ADMIN_PASSWORD='${PG_ADMIN_PASSWORD}' # admin permissions password
PG_SUPER_PASSWORD='${PG_SUPER_PASSWORD}' # all permissions password
PG_WRITE_PASSWORD='${PG_WRITE_PASSWORD}' # write permissions only password
PG__LOGTO_MANAGER_PASSWORD='${PG_ADMIN_PASSWORD}' # admin permissions only password
REDIS_PASSWORD='${REDIS_PASSWORD}' # redis password
LOGTO_API_M2M_CLIENT_ID='${LOGTO_API_M2M_CLIENT_ID}' # password
LOGTO_API_M2M_CLIENT_SECRET='${LOGTO_API_M2M_CLIENT_SECRET}' # password
Expand Down
2 changes: 1 addition & 1 deletion services/alp-logto/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ COPY experience.zip .
RUN unzip experience.zip

###### [STAGE] Seal ######
FROM ghcr.io/logto-io/logto:1.18
FROM ghcr.io/data2evidence/logto-with-logto-schema:develop

WORKDIR /etc/logto
RUN apk update && apk add openssl>3
Expand Down
6 changes: 3 additions & 3 deletions services/alp-logto/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ RUN npm add --location=global pnpm@^9.0.0
RUN apk add --no-cache python3 make g++ rsync py3-setuptools git

## Git clone
RUN git clone --branch v1.18.0 https://github.com/logto-io/logto.git /etc/logto
# TODO: clone d2e logto instead of public repo
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Task created

RUN git clone --branch v1.23.1 https://github.com/logto-io/logto.git /etc/logto

### Install dependencies and build ###
RUN node .scripts/update-parcelrc.js
RUN pnpm i

### Set if dev features enabled ###
Expand Down Expand Up @@ -47,6 +47,7 @@ RUN rm -rf .scripts .parcel-cache pnpm-*.yaml packages/cloud
FROM node:20-alpine as app
WORKDIR /etc/logto
COPY --from=builder /etc/logto .
RUN mkdir -p /etc/logto/packages/cli/alteration-scripts && chmod g+w /etc/logto/packages/cli/alteration-scripts

COPY ./connector-alp-azuread /etc/logto/packages/connectors/connector-alp-azuread

Expand All @@ -58,7 +59,6 @@ RUN yarn build
WORKDIR /etc/logto/

RUN npx @logto/cli connector link

EXPOSE 3001
ENTRYPOINT ["npm", "run"]
CMD ["start"]
Binary file modified services/alp-logto/experience.zip
Binary file not shown.
10 changes: 5 additions & 5 deletions services/alp-logto/post-init/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ async function seeding_alp_admin() {
);
await queryPostgres(
client,
"INSERT INTO public.applications(tenant_id, id, name, secret, description, type, oidc_client_metadata) \
"INSERT INTO applications(tenant_id, id, name, secret, description, type, oidc_client_metadata) \
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT(id) \
DO UPDATE SET secret = EXCLUDED.secret, oidc_client_metadata = EXCLUDED.oidc_client_metadata, custom_client_metadata = EXCLUDED.custom_client_metadata",
[
Expand All @@ -544,7 +544,7 @@ async function seeding_alp_admin() {
console.log(`Inserting ${alpAdminRole.name} role to roles table`);
await queryPostgres(
client,
"INSERT INTO public.roles(tenant_id, id, name, description, type) \
"INSERT INTO roles(tenant_id, id, name, description, type) \
VALUES ($1, $2, $3, $4, $5) ON CONFLICT(id) \
DO NOTHING;",
[
Expand All @@ -564,7 +564,7 @@ async function seeding_alp_admin() {
);
await queryPostgres(
client,
"INSERT INTO public.applications_roles(tenant_id, id, application_id, role_id) \
"INSERT INTO applications_roles(tenant_id, id, application_id, role_id) \
VALUES ($1, $2, $3, $4) ON CONFLICT(id) \
DO NOTHING;",
[
Expand All @@ -581,7 +581,7 @@ async function seeding_alp_admin() {
console.log(`Adding scope "management-api-all" to role ${alpAdminRole.name}`);
await queryPostgres(
client,
"INSERT INTO public.roles_scopes(tenant_id, id, role_id, scope_id) \
"INSERT INTO roles_scopes(tenant_id, id, role_id, scope_id) \
VALUES ($1, $2, $3, $4) ON CONFLICT(id) \
DO NOTHING;",
[
Expand Down Expand Up @@ -613,7 +613,7 @@ async function seeding_apps() {
console.log(`Seeding app ${envapp.name} | id ${envapp.id}`);
await queryPostgres(
client,
`INSERT INTO public.applications(tenant_id, id, name, secret, description, type, oidc_client_metadata)
`INSERT INTO applications(tenant_id, id, name, secret, description, type, oidc_client_metadata)
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT(id)
DO UPDATE SET secret = EXCLUDED.secret`,
[
Expand Down
58 changes: 38 additions & 20 deletions services/alp-logto/to-replace/SignIn/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { useEffect } from 'react';
import { useLocation, useSearchParams } from 'react-router-dom';
import { type SignIn, type ExperienceSocialConnector, AgreeToTermsPolicy } from '@logto/schemas';
import { useEffect } from "react";
import { useLocation, useSearchParams } from "react-router-dom";
import {
type SignIn,
type ExperienceSocialConnector,
AgreeToTermsPolicy,
} from "@logto/schemas";

import LoadingLayer from '@/components/LoadingLayer';
import SocialSignInList from '@/containers/SocialSignInList';
import TermsAndPrivacyCheckbox from '@/containers/TermsAndPrivacyCheckbox';
import useTerms from '@/hooks/use-terms';
import useSocial from '@/containers/SocialSignInList/use-social';
import LoadingLayer from "@/components/LoadingLayer";
import IdentifierSignInForm from "@/components/IdentifierSignInForm";
import PasswordSignInForm from "@/components/PasswordSignInForm";
import SocialSignInList from "@/containers/SocialSignInList";
import TermsAndPrivacyCheckbox from "@/containers/TermsAndPrivacyCheckbox";
import useSocial from "@/containers/SocialSignInList/use-social";
import useTerms from "@/hooks/use-terms";

import IdentifierSignInForm from './IdentifierSignInForm';
import PasswordSignInForm from './PasswordSignInForm';
import * as styles from './index.module.scss';
import styles from "./index.module.scss";

type Props = {
readonly signInMethods: SignIn['methods'];
readonly signInMethods: SignIn["methods"];
readonly socialConnectors: ExperienceSocialConnector[];
};

Expand All @@ -22,23 +26,30 @@ const Main = ({ signInMethods, socialConnectors }: Props) => {
const { invokeSocialSignIn } = useSocial();
const { pathname } = useLocation();
const [searchParameters] = useSearchParams();
const isPreview = searchParameters.has('preview')
const isRedirecting = pathname === "/sign-in" && !isPreview && signInMethods.length === 0 && socialConnectors.length === 1
const isPreview = searchParameters.has("preview");
const isRedirecting =
pathname === "/sign-in" &&
!isPreview &&
signInMethods.length === 0 &&
socialConnectors.length === 1;

useEffect(() => {
if (isRedirecting) {
socialConnectors[0] && invokeSocialSignIn(socialConnectors[0])
socialConnectors[0] && invokeSocialSignIn(socialConnectors[0]);
}
}, [isRedirecting])
}, [isRedirecting]);

if (isRedirecting) {
return <LoadingLayer />
return <LoadingLayer />;
}

if (signInMethods.length === 0 && socialConnectors.length > 0) {
return (
<>
<SocialSignInList className={styles.main} socialConnectors={socialConnectors} />
<SocialSignInList
className={styles.main}
socialConnectors={socialConnectors}
/>
{
/**
* Display agreement checkbox when only social sign-in methods are available
Expand All @@ -54,7 +65,9 @@ const Main = ({ signInMethods, socialConnectors }: Props) => {

const isPasswordOnly =
signInMethods.length > 0 &&
signInMethods.every(({ password, verificationCode }) => password && !verificationCode);
signInMethods.every(
({ password, verificationCode }) => password && !verificationCode
);

if (isPasswordOnly) {
return (
Expand All @@ -66,7 +79,12 @@ const Main = ({ signInMethods, socialConnectors }: Props) => {
}

if (signInMethods.length > 0) {
return <IdentifierSignInForm className={styles.main} signInMethods={signInMethods} />;
return (
<IdentifierSignInForm
className={styles.main}
signInMethods={signInMethods}
/>
);
}

return null;
Expand Down
20 changes: 19 additions & 1 deletion services/alp-pg-management/app/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type pgUsers = {
writerPassword: string;
manager: string;
managerPassword: string;
logtoManager: string;
logtoManagerPassword: string;
};

export class App {
Expand Down Expand Up @@ -155,6 +157,11 @@ export class App {
pgUsers.managerPassword,
"Manager"
);
await this.userDao.createUserWithCreateRolePrivilege(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logtoManager will need privileges to create new roles. Logto database migrations include creation of logto_tenant_<db>_default/admin users.

client,
pgUsers.logtoManager,
pgUsers.logtoManagerPassword
);

await this.dbDao.closeConnection(client);
} catch (e: any) {
Expand Down Expand Up @@ -245,7 +252,14 @@ export class App {
await this.userDao.grantManagePrivilegesForSchema(
client,
schemaName,
pgUsers.manager
pgUsers.manager,
false
);
await this.userDao.grantManagePrivilegesForSchema(
client,
schemaName,
pgUsers.logtoManager,
true
);
await this.userDao.grantUsageSchemaPrivileges(
client,
Expand Down Expand Up @@ -343,6 +357,10 @@ export class App {
databaseName,
this.getPGUsers(databaseName).manager
);
await this.grantCreatePrivilegesForDatabase(
databaseName,
this.getPGUsers(databaseName).logtoManager
);
const schemas = databases[database]["schemas"];
for (let schema of Object.keys(schemas)) {
if (schema.startsWith("+")) {
Expand Down
Loading
Loading