forked from baron/baron-sso
병합 이후 검토 적용
This commit is contained in:
@@ -205,7 +205,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
go-version: "1.26.2"
|
||||
cache-dependency-path: backend/go.sum
|
||||
|
||||
- name: Setup Flutter
|
||||
@@ -318,7 +318,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
go-version: "1.26.2"
|
||||
cache-dependency-path: backend/go.sum
|
||||
|
||||
- name: Run backend tests
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { createApiKey } from "../../lib/adminApi";
|
||||
@@ -50,15 +49,13 @@ describe("ApiKeyCreatePage", () => {
|
||||
});
|
||||
|
||||
it("includes org-context:read in the create request when selected", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderPage();
|
||||
|
||||
await user.type(
|
||||
screen.getByLabelText("서비스 또는 목적 식별 이름"),
|
||||
"org-context-client",
|
||||
);
|
||||
await user.click(screen.getByRole("button", { name: /조직 Context 조회/ }));
|
||||
await user.click(screen.getByRole("button", { name: /API 키 발급하기/ }));
|
||||
fireEvent.change(screen.getByLabelText("서비스 또는 목적 식별 이름"), {
|
||||
target: { value: "org-context-client" },
|
||||
});
|
||||
fireEvent.click(screen.getByRole("button", { name: /조직 Context 조회/ }));
|
||||
fireEvent.click(screen.getByRole("button", { name: /API 키 발급하기/ }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createApiKey).toHaveBeenCalledWith(
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { DomainTagInput } from "./DomainTagInput";
|
||||
|
||||
describe("DomainTagInput", () => {
|
||||
it("shows a clear duplicate tenant warning and adds the domain after confirmation", async () => {
|
||||
const user = userEvent.setup();
|
||||
const onChange = vi.fn();
|
||||
const onConfirmedConflictsChange = vi.fn();
|
||||
|
||||
@@ -34,10 +32,9 @@ describe("DomainTagInput", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.type(
|
||||
screen.getByPlaceholderText("example.com"),
|
||||
"samaneng.com ",
|
||||
);
|
||||
const input = screen.getByPlaceholderText("example.com");
|
||||
fireEvent.change(input, { target: { value: "samaneng.com" } });
|
||||
fireEvent.keyDown(input, { key: " " });
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
@@ -45,7 +42,7 @@ describe("DomainTagInput", () => {
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "계속 진행" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "계속 진행" }));
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(["samaneng.com"]);
|
||||
expect(onConfirmedConflictsChange).toHaveBeenCalledWith(["samaneng.com"]);
|
||||
|
||||
31
backups/baron-sso-backup-20260615-105417Z/checksums.sha256
Normal file
31
backups/baron-sso-backup-20260615-105417Z/checksums.sha256
Normal file
@@ -0,0 +1,31 @@
|
||||
5d2d06696fa6813d604ae0fc4a41d83018d3f58fa81c816533fe00c7ba46da48 ./clickhouse/baron_clickhouse/data/baron_sso__audit_logs.native
|
||||
d12b45688b414137a44d7162514756b33617046bb5bd2a2fe553d001e9ca7738 ./clickhouse/baron_clickhouse/data/baron_sso__rp_usage_daily_aggregate.native
|
||||
1418f34f8c5616446ac91c20e8c5efe451e4fcbbeb1c9acfd55552c02425e725 ./clickhouse/baron_clickhouse/data/baron_sso__rp_usage_events.native
|
||||
9b3eac049187af79f4db488b96f66b5a835807b37c8273cc4fa044e54ff6e1b2 ./clickhouse/baron_clickhouse/schema/baron_sso__audit_logs.sql
|
||||
6bd39d8db64aad6ef55ff5b9db11993ccf37a3fe1c49460c0e62099a4391925b ./clickhouse/baron_clickhouse/schema/baron_sso__rp_usage_daily_aggregate.sql
|
||||
1b502fcfa9ff305dcd5b4769ff727b6f2500769cf39b37fb780f65a0e609de2a ./clickhouse/baron_clickhouse/schema/baron_sso__rp_usage_daily_aggregate_mv.sql
|
||||
3515ed1f15426aae56b6cc12c4281c456d84477f1571a7ad002cc1869d82c9cd ./clickhouse/baron_clickhouse/schema/baron_sso__rp_usage_events.sql
|
||||
9c800f51db9a4143fbefb1c79d2046fa85ef66b3174941e17090cb2c4999b7d4 ./clickhouse/baron_clickhouse/tables.tsv
|
||||
db941d2a9be77eefba1a361cf36265abc09b8392580eaee7da8f037ca1ab6cd8 ./clickhouse/ory_clickhouse/data/ory__oathkeeper_access_logs.native
|
||||
1ee61755b025e757d8f0ea5208d083d4b36d68ea2f79fa3eb34e82b9e53eb7a8 ./clickhouse/ory_clickhouse/schema/ory__oathkeeper_access_logs.sql
|
||||
214144ca9cdbebde7270738176ffea9d0042dcdad2133b43dc0b1f107cf6197e ./clickhouse/ory_clickhouse/tables.tsv
|
||||
eefcef288ff99ff8477002e4f979e4ea801f5999e65b5e132c6f58182d87049f ./config/compose/compose.infra.yaml
|
||||
1c5f4eeae27b294711ea4a5dc5edcb87523724459fba37c6d0868ad11864df1d ./config/compose/compose.ory.yaml
|
||||
0c57362f2fbf33985d2a3162dba76af8b9860614d94c100fdb3e21f2f1779d8f ./config/compose/docker-compose.yaml
|
||||
8a670f1cff98b75fb8c7f240a6b38d0170fcf85ad40f8680ebd9260a95c64064 ./config/env.redacted
|
||||
15359cf3f3f96d522ccbd1311ac0811a9b6c3dfae1c4cd9809e85e02787e59af ./config/gateway.tar.zst
|
||||
125f45e479a0d71b0bed760429c6473bbacfc849ce37a673a03afe829f0cb714 ./config/generated-ory.tar.zst
|
||||
2108fc3d39c9a29a72759a7b1c1c344bc82915ecef2672b57d6d5f527c8e1284 ./manifest.json
|
||||
180986d8e311119606ee1cb021458507086285d960805473a1ce0f2ec00c76f4 ./postgres/baron.dump
|
||||
9c1c9939132d0ac1b260dd38ff7278382511cc1577ef792c5d2e45eb63c01e66 ./postgres/globals.sql
|
||||
cdf0b5f06148c88027e32515542fb452dfa40429077d8ecaa7dff4c250830f5e ./postgres/ory_hydra.dump
|
||||
240557fec153b4660ce4e10feeba09398a4ff35dec26b20675c4cb00725438b2 ./postgres/ory_keto.dump
|
||||
38060e8fe88f86b17b55d745dd6be602b036e68634c6190946c64728b0ac6e6e ./postgres/ory_kratos.dump
|
||||
e5a062101176bd89c36974ef5edafe43e8b9efacd492c023e46705af158c72ec ./reports/backup-report.md
|
||||
c08472517cf91b001f5cf4dbcf9750460e07ab1f7cd0f953aba79067899a724a ./reports/baron-postgres-custom-claim-counts.txt
|
||||
a301238b58845a6aa3d2b6f91bbec73fb672040f3527cb12b181a81272fc9793 ./reports/baron-postgres-row-counts.txt
|
||||
c8e6e5b0ee8c6eb360581aa0ee6120fd839308fe4d457ffb56749f7d4248184e ./reports/baron_clickhouse-row-counts.txt
|
||||
6b307b0f5be3a386c8b61198af2db45552c6c02992461b9e83eb38fc8f95f75b ./reports/ory_clickhouse-row-counts.txt
|
||||
fa92334662870832724702f2ac933a942709cae8ec8659b7e004647fc548ad1e ./reports/ory_hydra-row-counts.txt
|
||||
6d673a8360ab4a250d7f3ff77796444c26fa1ba66db8c341f01a8c01d15b9aea ./reports/ory_keto-row-counts.txt
|
||||
57484ccd98112c483f6cc903e8fb135bc8c60d6ca3ba1b9733f0859227b6919d ./reports/ory_kratos-row-counts.txt
|
||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
|
||||
event_dateDatecPdPdPdPhPhPhP…P…P…P…P†P†P†P†P†P†P‡P‡P‡P‡P‡P‡P‡P‡P tenant_idString$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$d4f7f478-fd3b-4ab2-b8f0-8515b45f4fac$3a660456-eceb-472b-a9a9-f2a5b0ce972b$52266543-a90b-4441-99c6-51f454b6059a$52266543-a90b-4441-99c6-51f454b6059a$78f251f6-d35b-422d-92ab-7fabd80bef85$35cc1fdf-6c0e-4b0e-8ce8-1adc918b8cbf$35cc1fdf-6c0e-4b0e-8ce8-1adc918b8cbf$3d147a08-00b9-47c7-940a-d75c36a6ce81$78f251f6-d35b-422d-92ab-7fabd80bef85$78f251f6-d35b-422d-92ab-7fabd80bef85$78f251f6-d35b-422d-92ab-7fabd80bef85$35cc1fdf-6c0e-4b0e-8ce8-1adc918b8cbf$35cc1fdf-6c0e-4b0e-8ce8-1adc918b8cbf$3a660456-eceb-472b-a9a9-f2a5b0ce972b$3a660456-eceb-472b-a9a9-f2a5b0ce972b$3d147a08-00b9-47c7-940a-d75c36a6ce81$78f251f6-d35b-422d-92ab-7fabd80bef85$f36e2211-8cfd-4813-8618-34e606fe73ac$f36e2211-8cfd-4813-8618-34e606fe73actenant_typeStringORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATIONORGANIZATION client_idStringdevfront
|
||||
adminfrontdevfrontorgfront
|
||||
adminfrontdevfrontorgfrontorgfrontdevfrontorgfrontdevfront$37290c73-0e5f-4250-ac4d-7b173d6b6ee0devfront$2ddc94e5-6c0f-4456-a025-1c6f438fb046$2ddc94e5-6c0f-4456-a025-1c6f438fb046
|
||||
adminfrontdevfront$37290c73-0e5f-4250-ac4d-7b173d6b6ee0devfront
|
||||
adminfrontorgfront$2ddc94e5-6c0f-4456-a025-1c6f438fb046$2ddc94e5-6c0f-4456-a025-1c6f438fb046$24d6c092-4de1-42f0-af6d-e741f24313d0devfrontclient_nameStringDevFront
|
||||
AdminFrontDevFrontOrgFront
|
||||
AdminFrontDevFrontOrgFrontOrgFrontDevFrontOrgFrontDevFrontheadless-nodejs-reactDevFrontRetainingWallDesignRetainingWallDesign
|
||||
AdminFrontDevFrontheadless-nodejs-reactDevFront
|
||||
AdminFrontOrgFrontRetainingWallDesignRetainingWallDesign1ë°”ë¡ ì†Œí”„íŠ¸ì›¨ì–´ ì—…ë<E280A6>°ì<C2B0>´íЏ ì œí’ˆ 관리DevFront
|
||||
event_typeStringrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedrp_usage.authorization_grantedevents_countAggregateFunction(count)%X unique_subjects$AggregateFunction(uniqExact, String)7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>Ú7v
|
||||
Î6ÔÆuµ“KI>ÚÃÕ‚Kàƒ¼V¶…TæhªTH|õ<èØÑïi(•ªTH|õ<èØÑïi(•œÍ i8£þ¥Ýì‘‹<C2AD>_½®É5ÍëNPî
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE baron_sso.audit_logs
|
||||
(
|
||||
`event_id` String,
|
||||
`timestamp` DateTime DEFAULT now(),
|
||||
`user_id` String,
|
||||
`tenant_id` String,
|
||||
`event_type` String,
|
||||
`status` String,
|
||||
`ip_address` String,
|
||||
`user_agent` String,
|
||||
`device_id` String,
|
||||
`details` String
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY timestamp
|
||||
SETTINGS index_granularity = 8192
|
||||
@@ -0,0 +1,14 @@
|
||||
CREATE TABLE baron_sso.rp_usage_daily_aggregate
|
||||
(
|
||||
`event_date` Date,
|
||||
`tenant_id` String,
|
||||
`tenant_type` String,
|
||||
`client_id` String,
|
||||
`client_name` String,
|
||||
`event_type` String,
|
||||
`events_count` AggregateFunction(count),
|
||||
`unique_subjects` AggregateFunction(uniqExact, String)
|
||||
)
|
||||
ENGINE = AggregatingMergeTree
|
||||
ORDER BY (event_date, tenant_id, client_id, event_type)
|
||||
SETTINGS index_granularity = 8192
|
||||
@@ -0,0 +1,28 @@
|
||||
CREATE MATERIALIZED VIEW baron_sso.rp_usage_daily_aggregate_mv TO baron_sso.rp_usage_daily_aggregate
|
||||
(
|
||||
`event_date` Date,
|
||||
`tenant_id` String,
|
||||
`tenant_type` String,
|
||||
`client_id` String,
|
||||
`client_name` String,
|
||||
`event_type` String,
|
||||
`events_count` AggregateFunction(count),
|
||||
`unique_subjects` AggregateFunction(uniqExact, String)
|
||||
)
|
||||
AS SELECT
|
||||
toDate(occurred_at) AS event_date,
|
||||
tenant_id,
|
||||
tenant_type,
|
||||
client_id,
|
||||
any(client_name) AS client_name,
|
||||
event_type,
|
||||
countState() AS events_count,
|
||||
uniqExactState(subject) AS unique_subjects
|
||||
FROM baron_sso.rp_usage_events
|
||||
WHERE tenant_type IN ('COMPANY', 'ORGANIZATION')
|
||||
GROUP BY
|
||||
event_date,
|
||||
tenant_id,
|
||||
tenant_type,
|
||||
client_id,
|
||||
event_type
|
||||
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE baron_sso.rp_usage_events
|
||||
(
|
||||
`event_id` String,
|
||||
`occurred_at` DateTime64(3) DEFAULT now64(3),
|
||||
`event_type` String,
|
||||
`subject` String,
|
||||
`tenant_id` String,
|
||||
`tenant_type` String,
|
||||
`client_id` String,
|
||||
`client_name` String,
|
||||
`session_id` String,
|
||||
`scopes` Array(String),
|
||||
`source` String,
|
||||
`correlation_id` String,
|
||||
`payload` String
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY (occurred_at, event_id)
|
||||
SETTINGS index_granularity = 8192
|
||||
@@ -0,0 +1,4 @@
|
||||
baron_sso audit_logs MergeTree
|
||||
baron_sso rp_usage_daily_aggregate AggregatingMergeTree
|
||||
baron_sso rp_usage_events MergeTree
|
||||
baron_sso rp_usage_daily_aggregate_mv MaterializedView
|
||||
|
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
CREATE TABLE ory.oathkeeper_access_logs
|
||||
(
|
||||
`timestamp` DateTime64(3) DEFAULT now64(3),
|
||||
`request_id` String DEFAULT '',
|
||||
`method` String DEFAULT '',
|
||||
`path` String DEFAULT '',
|
||||
`status` UInt16 DEFAULT 0,
|
||||
`latency_ms` UInt32 DEFAULT 0,
|
||||
`client_id` String DEFAULT '',
|
||||
`rp` String DEFAULT '',
|
||||
`action` String DEFAULT '',
|
||||
`target` String DEFAULT '',
|
||||
`rule_id` String DEFAULT '',
|
||||
`host` String DEFAULT '',
|
||||
`scheme` String DEFAULT '',
|
||||
`query` String DEFAULT '',
|
||||
`upstream_url` String DEFAULT '',
|
||||
`subject` String DEFAULT '',
|
||||
`parent_session_id` String DEFAULT '',
|
||||
`client_ip` String DEFAULT '',
|
||||
`user_agent` String DEFAULT '',
|
||||
`referer` String DEFAULT '',
|
||||
`decision` String DEFAULT '',
|
||||
`bytes_in` UInt64 DEFAULT 0,
|
||||
`bytes_out` UInt64 DEFAULT 0,
|
||||
`trace_id` String DEFAULT '',
|
||||
`span_id` String DEFAULT '',
|
||||
`raw` String DEFAULT ''
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY (timestamp, request_id)
|
||||
TTL timestamp + toIntervalDay(30)
|
||||
SETTINGS index_granularity = 8192
|
||||
@@ -0,0 +1 @@
|
||||
ory oathkeeper_access_logs MergeTree
|
||||
|
@@ -0,0 +1,82 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: baron_postgres
|
||||
environment:
|
||||
POSTGRES_USER: ${DB_USER:-baron}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
|
||||
POSTGRES_DB: ${DB_NAME:-baron_sso}
|
||||
ports:
|
||||
- "${DB_PORT:-5432}:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./docker/init-metadata:/docker-entrypoint-initdb.d
|
||||
networks:
|
||||
- baron_net
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USER:-baron} -d ${DB_NAME:-baron_sso}",
|
||||
]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: always
|
||||
|
||||
clickhouse:
|
||||
image: clickhouse/clickhouse-server:latest
|
||||
container_name: baron_clickhouse
|
||||
restart: always
|
||||
volumes:
|
||||
- clickhouse_data:/var/lib/clickhouse
|
||||
environment:
|
||||
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-baron}
|
||||
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-password}
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: baron_redis
|
||||
restart: always
|
||||
command: redis-server --port 6389
|
||||
ports:
|
||||
- "6389:6389"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
gateway:
|
||||
build:
|
||||
context: ./gateway
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_gateway
|
||||
restart: always
|
||||
ports:
|
||||
- "${USERFRONT_PORT:-5000}:5000"
|
||||
networks:
|
||||
- baron_net
|
||||
- public_net
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:5000/"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
clickhouse_data:
|
||||
redis_data:
|
||||
|
||||
networks:
|
||||
baron_net:
|
||||
name: baron_net
|
||||
external: true
|
||||
driver: bridge
|
||||
public_net:
|
||||
name: public_net
|
||||
external: true
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
services:
|
||||
postgres_ory:
|
||||
image: postgres:${ORY_POSTGRES_TAG:-17-alpine}
|
||||
container_name: ory_postgres
|
||||
environment:
|
||||
- POSTGRES_USER=${ORY_POSTGRES_USER:-ory}
|
||||
- POSTGRES_PASSWORD=${ORY_POSTGRES_PASSWORD:-secret}
|
||||
- POSTGRES_DB=${ORY_POSTGRES_DB:-ory}
|
||||
volumes:
|
||||
- ./docker/ory/init-db:/docker-entrypoint-initdb.d
|
||||
- ory_postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- ory-net
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${ORY_POSTGRES_USER:-ory} -d ${KRATOS_DB:-ory_kratos}",
|
||||
]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# --- Kratos ---
|
||||
kratos-migrate:
|
||||
image: oryd/kratos:${KRATOS_VERSION:-v26.2.0}
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB:-ory_kratos}?sslmode=disable&max_conns=20
|
||||
- KRATOS_SERVE_PUBLIC_BASE_URL=${KRATOS_BROWSER_URL}
|
||||
- KRATOS_SERVE_ADMIN_BASE_URL=${KRATOS_ADMIN_URL}
|
||||
- KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}
|
||||
- KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${KRATOS_UI_URL}/","${USERFRONT_URL}","${USERFRONT_URL}/","${USERFRONT_URL}/ko","${USERFRONT_URL}/ko/","${USERFRONT_URL}/en","${USERFRONT_URL}/en/","${USERFRONT_URL}/auth/callback","${USERFRONT_URL}/ko/auth/callback","${USERFRONT_URL}/en/auth/callback","${ADMINFRONT_URL}/auth/callback","${DEVFRONT_URL}/auth/callback","${ORGFRONT_URL}/auth/callback"]}
|
||||
- KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL}/error
|
||||
- KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL}/error?error=settings_disabled
|
||||
- KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL}/recovery
|
||||
- KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL}/verification
|
||||
- KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL}/login
|
||||
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
|
||||
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
|
||||
volumes:
|
||||
- ./config/.generated/ory/kratos:/etc/config/kratos
|
||||
command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes
|
||||
depends_on:
|
||||
postgres_ory:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
kratos:
|
||||
image: oryd/kratos:${KRATOS_VERSION:-v26.2.0}
|
||||
container_name: ory_kratos
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB:-ory_kratos}?sslmode=disable&max_conns=20
|
||||
- COOKIE_SECRET=${COOKIE_SECRET:-localcookie123}
|
||||
- KRATOS_SERVE_PUBLIC_BASE_URL=${KRATOS_BROWSER_URL}
|
||||
- KRATOS_SERVE_ADMIN_BASE_URL=${KRATOS_ADMIN_URL}
|
||||
- KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}
|
||||
- KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${KRATOS_UI_URL}/","${USERFRONT_URL}","${USERFRONT_URL}/","${USERFRONT_URL}/ko","${USERFRONT_URL}/ko/","${USERFRONT_URL}/en","${USERFRONT_URL}/en/","${USERFRONT_URL}/auth/callback","${USERFRONT_URL}/ko/auth/callback","${USERFRONT_URL}/en/auth/callback","${ADMINFRONT_URL}/auth/callback","${DEVFRONT_URL}/auth/callback","${ORGFRONT_URL}/auth/callback"]}
|
||||
- KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL}/error
|
||||
- KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL}/error?error=settings_disabled
|
||||
- KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL}/recovery
|
||||
- KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL}/verification
|
||||
- KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL}/login
|
||||
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
|
||||
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
|
||||
volumes:
|
||||
- ./config/.generated/ory/kratos:/etc/config/kratos
|
||||
command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
|
||||
depends_on:
|
||||
kratos-migrate:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- ory-net
|
||||
- kratosnet
|
||||
|
||||
# --- Hydra ---
|
||||
hydra-migrate:
|
||||
image: oryd/hydra:${HYDRA_VERSION:-v26.2.0}
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${HYDRA_DB:-ory_hydra}?sslmode=disable&max_conns=20
|
||||
command: migrate sql up -e --yes
|
||||
depends_on:
|
||||
postgres_ory:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
hydra:
|
||||
image: oryd/hydra:${HYDRA_VERSION:-v26.2.0}
|
||||
container_name: ory_hydra
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${HYDRA_DB:-ory_hydra}?sslmode=disable&max_conns=20
|
||||
- URLS_SELF_ISSUER=${HYDRA_PUBLIC_URL}
|
||||
- URLS_LOGIN=${HYDRA_LOGIN_URL:-${USERFRONT_URL}/login}
|
||||
- URLS_CONSENT=${HYDRA_CONSENT_URL:-${USERFRONT_URL}/consent}
|
||||
- URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error}
|
||||
- SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- ./config/.generated/ory/hydra:/etc/config/hydra
|
||||
command: serve -c /etc/config/hydra/hydra.yml all --dev
|
||||
depends_on:
|
||||
hydra-migrate:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- ory-net
|
||||
- hydranet
|
||||
|
||||
# --- Keto ---
|
||||
keto-migrate:
|
||||
image: oryd/keto:${KETO_VERSION:-v26.2.0}
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
|
||||
volumes:
|
||||
- ./config/.generated/ory/keto:/etc/config/keto
|
||||
command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"]
|
||||
depends_on:
|
||||
postgres_ory:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
keto:
|
||||
image: oryd/keto:${KETO_VERSION:-v26.2.0}
|
||||
container_name: ory_keto
|
||||
environment:
|
||||
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
|
||||
volumes:
|
||||
- ./config/.generated/ory/keto:/etc/config/keto
|
||||
command: serve -c /etc/config/keto/keto.yml
|
||||
depends_on:
|
||||
keto-migrate:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
# --- Oathkeeper ---
|
||||
oathkeeper_logs_init:
|
||||
image: alpine:latest
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"mkdir -p /var/log/oathkeeper && chown -R ${OATHKEEPER_UID:-1001}:${OATHKEEPER_GID:-1001} /var/log/oathkeeper",
|
||||
]
|
||||
volumes:
|
||||
- oathkeeper_logs:/var/log/oathkeeper
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
oathkeeper:
|
||||
image: oryd/oathkeeper:${OATHKEEPER_VERSION:-v26.2.0}
|
||||
container_name: ory_oathkeeper
|
||||
user: "${OATHKEEPER_UID:-1001}:${OATHKEEPER_GID:-1001}"
|
||||
ports:
|
||||
- "4457:4455" # Proxy
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- LOG_LEVEL=debug
|
||||
- OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
|
||||
- OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
|
||||
volumes:
|
||||
- ./config/.generated/ory/oathkeeper:/etc/config/oathkeeper
|
||||
- oathkeeper_logs:/var/log/oathkeeper
|
||||
entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
|
||||
depends_on:
|
||||
oathkeeper_logs_init:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- ory-net
|
||||
- public_net
|
||||
|
||||
ory_clickhouse:
|
||||
image: clickhouse/clickhouse-server:latest
|
||||
container_name: ory_clickhouse
|
||||
environment:
|
||||
- CLICKHOUSE_USER=${ORY_CLICKHOUSE_USER:-ory}
|
||||
- CLICKHOUSE_PASSWORD=${ORY_CLICKHOUSE_PASSWORD:-orypass}
|
||||
volumes:
|
||||
- ory_clickhouse_data:/var/lib/clickhouse
|
||||
- ./docker/ory/clickhouse:/docker-entrypoint-initdb.d
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
ory_vector:
|
||||
image: timberio/vector:0.36.0-alpine
|
||||
container_name: ory_vector
|
||||
environment:
|
||||
- ORY_CLICKHOUSE_USER=${ORY_CLICKHOUSE_USER:-ory}
|
||||
- ORY_CLICKHOUSE_PASSWORD=${ORY_CLICKHOUSE_PASSWORD:-orypass}
|
||||
volumes:
|
||||
- ./docker/ory/vector:/etc/vector
|
||||
- oathkeeper_logs:/var/log/oathkeeper
|
||||
command: ["-c", "/etc/vector/vector.toml"]
|
||||
depends_on:
|
||||
- oathkeeper
|
||||
- ory_clickhouse
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
# --- 초기화 & 헬스체크 ---
|
||||
ory_stack_check:
|
||||
image: alpine:latest
|
||||
container_name: ory_stack_check
|
||||
command: >
|
||||
/bin/sh -c "
|
||||
apk add --no-cache curl;
|
||||
echo 'Wait for services...';
|
||||
check_ready() {
|
||||
name=\"$$1\";
|
||||
url=\"$$2\";
|
||||
max=\"$${ORY_STACK_CHECK_MAX_ATTEMPTS:-60}\";
|
||||
i=1;
|
||||
while [ \"$$i\" -le \"$$max\" ]; do
|
||||
if curl --connect-timeout 2 --max-time 3 -fsS \"$$url\" >/dev/null; then
|
||||
echo \"Ory service ready: $$name\";
|
||||
return 0;
|
||||
fi;
|
||||
echo \"Waiting for Ory service: $$name ($$i/$$max)\";
|
||||
i=$$((i + 1));
|
||||
sleep 1;
|
||||
done;
|
||||
echo \"ERROR: Ory service not ready: $$name after $$max attempts ($$url)\" >&2;
|
||||
echo \"ERROR: Check service logs: docker logs ory_$$name\" >&2;
|
||||
return 1;
|
||||
};
|
||||
check_ready kratos http://kratos:4433/health/ready || exit 1;
|
||||
check_ready hydra http://hydra:4444/health/ready || exit 1;
|
||||
check_ready keto http://keto:4466/health/ready || exit 1;
|
||||
echo 'Ory Stack is fully operational!';"
|
||||
depends_on:
|
||||
- kratos
|
||||
- hydra
|
||||
- keto
|
||||
networks:
|
||||
- ory-net
|
||||
|
||||
# 기본 RP (Admin Front 등) 자동 등록 컨테이너
|
||||
init-rp:
|
||||
image: oryd/hydra:${HYDRA_CLI_VERSION:-v26.2.0}
|
||||
env_file:
|
||||
- .env
|
||||
entrypoint: ["/bin/sh", "-ec"]
|
||||
command:
|
||||
- |
|
||||
hydra delete oauth2-client --endpoint "$${HYDRA_ADMIN_URL}" adminfront >/dev/null 2>&1 || true
|
||||
hydra delete oauth2-client --endpoint "$${HYDRA_ADMIN_URL}" devfront >/dev/null 2>&1 || true
|
||||
hydra delete oauth2-client --endpoint "$${HYDRA_ADMIN_URL}" orgfront >/dev/null 2>&1 || true
|
||||
hydra delete oauth2-client --endpoint "$${HYDRA_ADMIN_URL}" "$${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}" >/dev/null 2>&1 || true
|
||||
|
||||
hydra create oauth2-client \
|
||||
--endpoint "$${HYDRA_ADMIN_URL}" \
|
||||
--id adminfront \
|
||||
--name "AdminFront" \
|
||||
--grant-type authorization_code,refresh_token \
|
||||
--response-type code \
|
||||
--scope openid,offline_access,profile,email \
|
||||
--token-endpoint-auth-method none \
|
||||
--redirect-uri ${ADMINFRONT_CALLBACK_URLS}
|
||||
|
||||
hydra create oauth2-client \
|
||||
--endpoint "$${HYDRA_ADMIN_URL}" \
|
||||
--id devfront \
|
||||
--name "DevFront" \
|
||||
--grant-type authorization_code,refresh_token \
|
||||
--response-type code \
|
||||
--scope openid,offline_access,profile,email \
|
||||
--token-endpoint-auth-method none \
|
||||
--redirect-uri ${DEVFRONT_CALLBACK_URLS}
|
||||
|
||||
hydra create oauth2-client \
|
||||
--endpoint "$${HYDRA_ADMIN_URL}" \
|
||||
--id orgfront \
|
||||
--name "OrgFront" \
|
||||
--grant-type authorization_code,refresh_token \
|
||||
--response-type code \
|
||||
--scope openid,offline_access,profile,email \
|
||||
--token-endpoint-auth-method none \
|
||||
--redirect-uri ${ORGFRONT_CALLBACK_URLS}
|
||||
|
||||
hydra create oauth2-client \
|
||||
--endpoint "$${HYDRA_ADMIN_URL}" \
|
||||
--id "$${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}" \
|
||||
--secret "$${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}" \
|
||||
--grant-type client_credentials \
|
||||
--response-type token \
|
||||
--scope openid,offline_access,profile,email
|
||||
depends_on:
|
||||
ory_stack_check:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- hydranet
|
||||
|
||||
volumes:
|
||||
ory_postgres_data:
|
||||
ory_clickhouse_data:
|
||||
oathkeeper_logs:
|
||||
|
||||
networks:
|
||||
ory-net:
|
||||
external: true
|
||||
name: ory-net
|
||||
hydranet:
|
||||
external: true
|
||||
name: hydranet
|
||||
kratosnet:
|
||||
external: true
|
||||
name: kratosnet
|
||||
public_net:
|
||||
external: true
|
||||
name: public_net
|
||||
@@ -0,0 +1,223 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: baron_backend
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- GO_ENV=${APP_ENV:-development}
|
||||
- BACKEND_LOG_LEVEL=${BACKEND_LOG_LEVEL:-info}
|
||||
- CLIENT_LOG_DEBUG=${CLIENT_LOG_DEBUG:-false}
|
||||
- WORKS_ADMIN_API_BASE_URL=${WORKS_ADMIN_API_BASE_URL}
|
||||
- WORKS_ADMIN_OAUTH_TOKEN_URL=${WORKS_ADMIN_OAUTH_TOKEN_URL}
|
||||
- COOKIE_SECRET=${COOKIE_SECRET}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- NAVER_CLOUD_ACCESS_KEY=${NAVER_CLOUD_ACCESS_KEY}
|
||||
- NAVER_CLOUD_SECRET_KEY=${NAVER_CLOUD_SECRET_KEY}
|
||||
- NAVER_CLOUD_SERVICE_ID=${NAVER_CLOUD_SERVICE_ID}
|
||||
- NAVER_SENDER_PHONE_NUMBER=${NAVER_SENDER_PHONE_NUMBER}
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- REDIS_ADDR=${REDIS_ADDR}
|
||||
- IDP_PROVIDER=${IDP_PROVIDER:-ory}
|
||||
- KRATOS_ADMIN_URL=${KRATOS_ADMIN_URL:-http://kratos:4434}
|
||||
- HYDRA_ADMIN_URL=${HYDRA_ADMIN_URL:-http://hydra:4445}
|
||||
- HYDRA_PUBLIC_URL=${HYDRA_PUBLIC_URL:-http://hydra:4444}
|
||||
- KETO_READ_URL=${KETO_READ_URL:-http://keto:4466}
|
||||
- KETO_WRITE_URL=${KETO_WRITE_URL:-http://keto:4467}
|
||||
- DB_HOST=postgres
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT_NATIVE:-9000}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-baron}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
|
||||
- SEED_TENANT_CSV_PATH=/app/seed-tenant.csv
|
||||
depends_on:
|
||||
- infra_check
|
||||
networks:
|
||||
- baron_net
|
||||
- ory-net
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
- ./config:/app/config:ro
|
||||
- ./adminfront/seed-tenant.csv:/app/seed-tenant.csv:ro
|
||||
command: ["go", "run", "./cmd/server"]
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
adminfront:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./adminfront/Dockerfile
|
||||
args:
|
||||
VITE_ADMIN_PUBLIC_URL: ${ADMINFRONT_URL}
|
||||
VITE_OIDC_AUTHORITY: ${VITE_OIDC_AUTHORITY}
|
||||
VITE_OIDC_CLIENT_ID: adminfront
|
||||
container_name: baron_adminfront
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- API_PROXY_TARGET=http://baron_backend:3000
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- VITE_CLIENT_LOG_DEBUG=${VITE_CLIENT_LOG_DEBUG:-false}
|
||||
ports:
|
||||
- "${ADMINFRONT_PORT:-5173}:5173"
|
||||
volumes:
|
||||
- ./adminfront:/workspace/adminfront
|
||||
- ./common:/common
|
||||
- ./common:/workspace/common
|
||||
- /workspace/common/node_modules
|
||||
- ./locales:/locales
|
||||
- ./locales:/workspace/locales
|
||||
- /workspace/adminfront/node_modules
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
devfront:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./devfront/Dockerfile
|
||||
args:
|
||||
VITE_DEVFRONT_PUBLIC_URL: ${DEVFRONT_URL}
|
||||
VITE_OIDC_AUTHORITY: ${VITE_OIDC_AUTHORITY}
|
||||
VITE_OIDC_CLIENT_ID: devfront
|
||||
container_name: baron_devfront
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- API_PROXY_TARGET=http://baron_backend:3000
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- VITE_CLIENT_LOG_DEBUG=${VITE_CLIENT_LOG_DEBUG:-false}
|
||||
ports:
|
||||
- "${DEVFRONT_PORT:-5174}:5173"
|
||||
volumes:
|
||||
- ./devfront:/workspace/devfront
|
||||
- ./common:/common
|
||||
- ./common:/workspace/common
|
||||
- /workspace/common/node_modules
|
||||
- ./locales:/locales
|
||||
- ./locales:/workspace/locales
|
||||
- /workspace/devfront/node_modules
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
orgfront:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./orgfront/Dockerfile
|
||||
args:
|
||||
VITE_ORGFRONT_PUBLIC_URL: ${ORGFRONT_URL}
|
||||
VITE_OIDC_AUTHORITY: ${VITE_OIDC_AUTHORITY}
|
||||
VITE_OIDC_CLIENT_ID: orgfront
|
||||
container_name: baron_orgfront
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- API_PROXY_TARGET=http://baron_backend:3000
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- VITE_CLIENT_LOG_DEBUG=${VITE_CLIENT_LOG_DEBUG:-false}
|
||||
ports:
|
||||
- "${ORGFRONT_PORT:-5175}:5175"
|
||||
volumes:
|
||||
- ./orgfront:/workspace/orgfront
|
||||
- ./common:/common
|
||||
- ./common:/workspace/common
|
||||
- /workspace/common/node_modules
|
||||
- ./locales:/locales
|
||||
- ./locales:/workspace/locales
|
||||
- /workspace/orgfront/node_modules
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
|
||||
userfront:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: userfront/Dockerfile
|
||||
target: ${USERFRONT_BUILD_TARGET:-dev}
|
||||
container_name: baron_userfront
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- BACKEND_URL=${BACKEND_URL:-}
|
||||
- USERFRONT_URL=${USERFRONT_URL}
|
||||
- APP_ENV=${APP_ENV}
|
||||
- CLIENT_LOG_DEBUG=${CLIENT_LOG_DEBUG:-false}
|
||||
- USERFRONT_INTERNAL_PORT=5000
|
||||
- USERFRONT_FLUTTER_RUN_FLAGS=${USERFRONT_FLUTTER_RUN_FLAGS:-}
|
||||
volumes:
|
||||
- ./userfront/lib:/workspace/userfront/lib
|
||||
- ./userfront/assets:/workspace/userfront/assets
|
||||
- ./userfront/web:/workspace/userfront/web
|
||||
- ./userfront/scripts:/workspace/userfront/scripts:ro
|
||||
- ./scripts:/workspace/scripts:ro
|
||||
- ./locales:/workspace/locales:ro
|
||||
networks:
|
||||
- baron_net
|
||||
- ory-net
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:5000/"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Dummy service to wait for infra network if needed,
|
||||
# but essentially we assume infra is running.
|
||||
# In a real unified stack, we might include infra here or use external links.
|
||||
# Here we attach to the same network.
|
||||
infra_check:
|
||||
image: alpine
|
||||
command: ["echo", "Infrastructure assumed running"]
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
promtail:
|
||||
image: grafana/promtail:2.9.0
|
||||
container_name: baron_promtail
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
||||
- ./docker/promtail-config.template.yaml:/etc/promtail/promtail-config.yaml:ro
|
||||
command: -config.file=/etc/promtail/promtail-config.yaml -config.expand-env=true
|
||||
environment:
|
||||
- LOKI_URL=${LOKI_URL:-http://loki:3100/loki/api/v1/push}
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
networks:
|
||||
- baron_net
|
||||
|
||||
blackbox-exporter:
|
||||
image: prom/blackbox-exporter:v0.25.0
|
||||
container_name: baron_blackbox_exporter
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9115:9115"
|
||||
volumes:
|
||||
- ./docker/monitor/blackbox.yml:/etc/blackbox_exporter/config.yml:ro
|
||||
networks:
|
||||
- baron_net
|
||||
- ory-net
|
||||
|
||||
networks:
|
||||
baron_net:
|
||||
external: true
|
||||
name: baron_net
|
||||
ory-net:
|
||||
external: true
|
||||
name: ory-net
|
||||
public_net:
|
||||
external: true
|
||||
name: public_net
|
||||
120
backups/baron-sso-backup-20260615-105417Z/config/env.redacted
Normal file
120
backups/baron-sso-backup-20260615-105417Z/config/env.redacted
Normal file
@@ -0,0 +1,120 @@
|
||||
APP_ENV=dev
|
||||
BACKEND_LOG_LEVEL=debug
|
||||
CLIENT_LOG_DEBUG=true
|
||||
TZ=Asia/Seoul
|
||||
IDP_PROVIDER=ory
|
||||
|
||||
# DB & Clickhouse
|
||||
DB_PORT=5432
|
||||
CLICKHOUSE_PORT_HTTP=8123
|
||||
CLICKHOUSE_PORT_NATIVE=9000
|
||||
CLICKHOUSE_HOST=clickhouse
|
||||
CLICKHOUSE_USER=baron
|
||||
CLICKHOUSE_PASSWORD=REDACTED
|
||||
|
||||
|
||||
BACKEND_PORT=3000
|
||||
ADMINFRONT_PORT=5173
|
||||
DEVFRONT_PORT=5174
|
||||
ORGFRONT_PORT=5175
|
||||
USERFRONT_PORT=5000
|
||||
|
||||
OATHKEEPER_API_URL=http://oathkeeper:4456
|
||||
|
||||
DB_USER=baron
|
||||
DB_PASSWORD=REDACTED
|
||||
DB_NAME=baron_sso
|
||||
COOKIE_SECRET=REDACTED
|
||||
JWT_SECRET=REDACTED
|
||||
REDIS_ADDR=redis:6389
|
||||
CORS_ALLOWED_ORIGINS='*'
|
||||
AUDIT_WORKER_COUNT=5
|
||||
AUDIT_QUEUE_SIZE=2000
|
||||
PROFILE_CACHE_TTL=
|
||||
NAVER_CLOUD_ACCESS_KEY=REDACTED
|
||||
NAVER_CLOUD_SECRET_KEY=REDACTED
|
||||
NAVER_CLOUD_SERVICE_ID=ncp:sms:kr:364022321777:baroncs
|
||||
NAVER_SENDER_PHONE_NUMBER=0262857755
|
||||
AWS_REGION=ap-northeast-2
|
||||
AWS_ACCESS_KEY_ID=REDACTED
|
||||
AWS_SECRET_ACCESS_KEY=REDACTED
|
||||
AWS_SES_SENDER=support@baroncs.co.kr
|
||||
# ADMIN_EMAIL=admin@hmac.kr
|
||||
ADMIN_EMAIL=su-@samaneng.com
|
||||
ADMIN_PASSWORD=REDACTED
|
||||
USERFRONT_URL=http://localhost:5000
|
||||
# USERFRONT_URL=http://172.16.9.189:5000
|
||||
ADMINFRONT_URL=http://localhost:5173
|
||||
DEVFRONT_URL=http://localhost:5174
|
||||
VITE_ORGCHART_URL=http://localhost:5175
|
||||
ORGFRONT_URL=http://localhost:5175
|
||||
BACKEND_PUBLIC_URL=${USERFRONT_URL}
|
||||
BACKEND_URL=${USERFRONT_URL}
|
||||
# OATHKEEPER_PUBLIC_URL=http://172.16.9.189:5000
|
||||
OATHKEEPER_PUBLIC_URL=http://localhost:5000
|
||||
|
||||
ORY_POSTGRES_TAG=17-trixie
|
||||
ORY_POSTGRES_USER=ory
|
||||
ORY_POSTGRES_PASSWORD=REDACTED
|
||||
ORY_POSTGRES_DB=ory
|
||||
KRATOS_DB=ory_kratos
|
||||
HYDRA_DB=ory_hydra
|
||||
KETO_DB=ory_keto
|
||||
KRATOS_VERSION=v26.2.0-distroless
|
||||
HYDRA_VERSION=v26.2.0-distroless
|
||||
KETO_VERSION=v26.2.0-distroless
|
||||
ORY_SDK_URL=http://kratos:4433
|
||||
KRATOS_PUBLIC_URL=http://kratos:4433
|
||||
KRATOS_ADMIN_URL=http://kratos:4434
|
||||
KRATOS_BROWSER_URL=http://localhost:5000/auth
|
||||
KRATOS_UI_URL=http://localhost:5000
|
||||
HYDRA_ADMIN_URL=http://hydra:4445
|
||||
HYDRA_PUBLIC_URL=http://localhost:5000/oidc
|
||||
JWKS_URL=http://oathkeeper:4456/.well-known/jwks.json
|
||||
OATHKEEPER_VERSION=v26.2.0
|
||||
OATHKEEPER_UID=1001
|
||||
OATHKEEPER_GID=1001
|
||||
OATHKEEPER_HEALTH_URL=http://oathkeeper:4456/health/ready
|
||||
OATHKEEPER_HEALTH_INTERVAL_SECONDS=10
|
||||
OATHKEEPER_HEALTH_TIMEOUT_SECONDS=2
|
||||
OATHKEEPER_HEALTH_ENABLED=true
|
||||
CSRF_COOKIE_NAME=REDACTED
|
||||
CSRF_COOKIE_SECRET=REDACTED
|
||||
|
||||
# Frontend OIDC configs for Staging
|
||||
VITE_OIDC_AUTHORITY=http://localhost:5000/oidc
|
||||
ADMINFRONT_CALLBACK_URLS=http://localhost:5173/auth/callback
|
||||
DEVFRONT_CALLBACK_URLS=http://localhost:5174/auth/callback
|
||||
ORGFRONT_CALLBACK_URLS=http://localhost:5175/auth/callback
|
||||
# OATHKEEPER_INTROSPECT_CLIENT_ID=
|
||||
# OATHKEEPER_INTROSPECT_CLIENT_SECRET=
|
||||
|
||||
#Worksmobile
|
||||
SAMAN_DOMAIN_ID=300285955
|
||||
HANMAC_DOMAIN_ID=300286336
|
||||
GPDTDC_DOMAIN_ID=300286337
|
||||
BARONGROUP_DOMAIN_ID=300286645
|
||||
HALLA_DOMAIN_ID=300293726
|
||||
SAMAN_TENANT_ID=300285955
|
||||
SAMAN_SCIM_LONGLIVE_TOKEN=REDACTED
|
||||
WORKS_ADMIN_OAUTH_CLIENT_ID=JrD1iPz73ugTFV5XL_zO
|
||||
WORKS_ADMIN_OAUTH_CLIENT_SECRET=REDACTED
|
||||
WORKS_ADMIN_OAUTH_CLIENT_SERVICE_ACCOUNT=e3n9j.serviceaccount@samaneng.com
|
||||
WORKS_ADMIN_OAUTH_CLIENT_PRIVATE_KEY_FILE=REDACTED
|
||||
WORKS_DEFAULT_DOMAIN_SAMAN=samaneng.com
|
||||
WORKS_DEFAULT_DOMAIN_HANMAC=hanmaceng.co.kr
|
||||
WORKS_DEFAULT_DOMAIN_GPDTDC=baroncs.co.kr
|
||||
WORKS_DEFAULT_DOMAIN_BARONGROUP=brsw.kr
|
||||
WORKS_DEFAULT_DOMAIN_HALLA=hallasanup.com
|
||||
WORKS_ADMIN_API_BASE_URL=https://www.worksapis.com
|
||||
WORKS_ADMIN_OAUTH_TOKEN_URL=REDACTED
|
||||
|
||||
WORKS_DRIVE_OAUTH_CLIENT_ID=9JapAnmjI9M_1SqDp4Uj
|
||||
WORKS_DRIVE_OAUTH_CLIENT_SECRET=REDACTED
|
||||
WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT=h4bq6.serviceaccount@samaneng.com
|
||||
WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY_FILE=REDACTED
|
||||
WORKS_DRIVE_APP_PASSWORD=REDACTED
|
||||
WORKS_DRIVE_OAUTH_REDIRECT_URI=https://drive.hmac.kr/works/callback
|
||||
WORKS_DRIVE_OAUTH_REFRESH_TOKEN=REDACTED
|
||||
WORKS_DRIVE_SHARED_DRIVE_ID=@2001000000540386
|
||||
WORKS_DRIVE_PARENT_FILE_ID=QDIwMDEwMDAwMDA1NDAzODZ8MzQ3MjYxMzYwMzE0NjY2NDk2OXxEfDA
|
||||
BIN
backups/baron-sso-backup-20260615-105417Z/config/gateway.tar.zst
Normal file
BIN
backups/baron-sso-backup-20260615-105417Z/config/gateway.tar.zst
Normal file
Binary file not shown.
Binary file not shown.
14
backups/baron-sso-backup-20260615-105417Z/manifest.json
Normal file
14
backups/baron-sso-backup-20260615-105417Z/manifest.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"format_version": "1",
|
||||
"created_at": "2026-06-15T10:54:33Z",
|
||||
"git_commit": "4d468cd39f66",
|
||||
"mode": "maintenance",
|
||||
"environment_scope": "same-env-only",
|
||||
"services": ["postgres", "ory-postgres", "clickhouse", "ory-clickhouse", "config"],
|
||||
"restore_policy": {
|
||||
"requires_empty_target": true,
|
||||
"requires_confirmation": "baron-sso",
|
||||
"auto_run_migrations": false,
|
||||
"works_relay_auto_resume": false
|
||||
}
|
||||
}
|
||||
BIN
backups/baron-sso-backup-20260615-105417Z/postgres/baron.dump
Normal file
BIN
backups/baron-sso-backup-20260615-105417Z/postgres/baron.dump
Normal file
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
--
|
||||
-- PostgreSQL database cluster dump
|
||||
--
|
||||
|
||||
\restrict Nh0reka1aBJKKDfxlc9L4ubRixmPembXVECzqwEVE1GjdnFtzDPBHXZ6jU72Ib3
|
||||
|
||||
SET default_transaction_read_only = off;
|
||||
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
|
||||
--
|
||||
-- Roles
|
||||
--
|
||||
|
||||
CREATE ROLE ory;
|
||||
ALTER ROLE ory WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:MsUfyYDDHLEuU7R26Goauw==$VF6QHNq8fhkEWH4ZAM9daFbYrd6BzTyrg7ovbcPEZig=:4CpeffAwyfHv1hJjEvVj1XI2X6KRASciYL9TdXnoVSY=';
|
||||
|
||||
--
|
||||
-- User Configurations
|
||||
--
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\unrestrict Nh0reka1aBJKKDfxlc9L4ubRixmPembXVECzqwEVE1GjdnFtzDPBHXZ6jU72Ib3
|
||||
|
||||
--
|
||||
-- PostgreSQL database cluster dump complete
|
||||
--
|
||||
|
||||
Binary file not shown.
BIN
backups/baron-sso-backup-20260615-105417Z/postgres/ory_keto.dump
Normal file
BIN
backups/baron-sso-backup-20260615-105417Z/postgres/ory_keto.dump
Normal file
Binary file not shown.
Binary file not shown.
BIN
baron-sso-backup-20260615-105417Z.tar.zst
Normal file
BIN
baron-sso-backup-20260615-105417Z.tar.zst
Normal file
Binary file not shown.
@@ -143,7 +143,7 @@ test.describe("DevFront RP claim cache", () => {
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByText("offline_access", { exact: true }),
|
||||
page.getByRole("button", { name: /offline_access/ }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: /employee_code/ }),
|
||||
|
||||
@@ -872,7 +872,7 @@ title_with_code = "Error: {{code}}"
|
||||
type = "Error type: {{type}}"
|
||||
|
||||
[msg.userfront.error.ory]
|
||||
$normalizedCode = "{{error}}"
|
||||
"$normalizedCode" = "{{error}}"
|
||||
access_denied = "The user denied the consent request."
|
||||
consent_required = "Consent is required to continue."
|
||||
interaction_required = "Additional interaction is required. Please try again."
|
||||
@@ -904,7 +904,7 @@ tenant_unknown = "Unknown"
|
||||
title = "Access restriction details"
|
||||
|
||||
[msg.userfront.error.whitelist]
|
||||
$normalizedCode = "{{error}}"
|
||||
"$normalizedCode" = "{{error}}"
|
||||
bad_request = "Please check your input."
|
||||
invalid_session = "Your session has expired. Please sign in again."
|
||||
not_found = "The requested page could not be found."
|
||||
|
||||
@@ -872,7 +872,7 @@ title_with_code = "오류: {{code}}"
|
||||
type = "오류 종류: {{type}}"
|
||||
|
||||
[msg.userfront.error.ory]
|
||||
$normalizedCode = "{{error}}"
|
||||
"$normalizedCode" = "{{error}}"
|
||||
access_denied = "사용자가 동의를 거부했습니다."
|
||||
consent_required = "앱 접근 동의가 필요합니다."
|
||||
interaction_required = "추가 상호작용이 필요합니다. 다시 시도해 주세요."
|
||||
@@ -904,7 +904,7 @@ tenant_unknown = "알 수 없음"
|
||||
title = "접근 제한 정보"
|
||||
|
||||
[msg.userfront.error.whitelist]
|
||||
$normalizedCode = "{{error}}"
|
||||
"$normalizedCode" = "{{error}}"
|
||||
bad_request = "입력값을 확인해 주세요."
|
||||
invalid_session = "세션이 만료되었습니다. 다시 로그인해 주세요."
|
||||
not_found = "요청한 페이지를 찾을 수 없습니다."
|
||||
|
||||
@@ -872,7 +872,7 @@ title_with_code = ""
|
||||
type = ""
|
||||
|
||||
[msg.userfront.error.ory]
|
||||
$normalizedCode = ""
|
||||
"$normalizedCode" = ""
|
||||
access_denied = ""
|
||||
consent_required = ""
|
||||
interaction_required = ""
|
||||
@@ -904,7 +904,7 @@ tenant_unknown = ""
|
||||
title = ""
|
||||
|
||||
[msg.userfront.error.whitelist]
|
||||
$normalizedCode = ""
|
||||
"$normalizedCode" = ""
|
||||
bad_request = ""
|
||||
invalid_session = ""
|
||||
not_found = ""
|
||||
|
||||
@@ -63,7 +63,7 @@ description = "Toggle to view only active sessions."
|
||||
accept_error = "Failed to process consent: {error}"
|
||||
client_id = "Client ID: {id}"
|
||||
client_unknown = "Unknown application"
|
||||
description = "The service below is requesting access to your account information.\\\\\\\\nPlease choose whether to continue."
|
||||
description = "The service below is requesting access to your account information.\\\\\\\\\\\\\\\\nPlease choose whether to continue."
|
||||
load_error = "Failed to load consent information: {error}"
|
||||
missing_redirect = "Consent was processed, but the redirect URL was missing."
|
||||
redirect_notice = "After consent, you will be redirected automatically."
|
||||
@@ -103,12 +103,12 @@ empty_detail = "Linked apps and their latest activity will appear here."
|
||||
error = "Could not load linked apps."
|
||||
|
||||
[msg.userfront.dashboard.approved_session]
|
||||
copy_click = "{label}: {id}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nClick to copy."
|
||||
copy_tap = "{label}: {id}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nTap to copy."
|
||||
copy_click = "{label}: {id}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nClick to copy."
|
||||
copy_tap = "{label}: {id}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nTap to copy."
|
||||
none = "No {label}"
|
||||
|
||||
[msg.userfront.dashboard.revoke]
|
||||
confirm = "Disconnect {app}?\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nYou will need to grant access again the next time you sign in."
|
||||
confirm = "Disconnect {app}?\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nYou will need to grant access again the next time you sign in."
|
||||
error = "Could not disconnect the app: {error}"
|
||||
success = "{app} has been disconnected."
|
||||
|
||||
@@ -125,7 +125,7 @@ recent_app = "Recent app: {app}"
|
||||
session_id = "Session ID: {id}"
|
||||
|
||||
[msg.userfront.dashboard.sessions.revoke]
|
||||
confirm = "End the session for {target}?\\nThat device will need to sign in again."
|
||||
confirm = "End the session for {target}?\\\\nThat device will need to sign in again."
|
||||
error = "Could not end the session: {error}"
|
||||
success = "The session has been ended."
|
||||
|
||||
@@ -229,7 +229,7 @@ scan_hint = "Scan it with the mobile app."
|
||||
invalid = "Enter the 2 letters and 6 digits from your code."
|
||||
|
||||
[msg.userfront.login.unregistered]
|
||||
body = "We could not find an account for that information.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nPlease sign up before continuing."
|
||||
body = "We could not find an account for that information.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nPlease sign up before continuing."
|
||||
|
||||
[msg.userfront.login.verification]
|
||||
approved = "Approved. Complete sign-in in the original window."
|
||||
|
||||
@@ -63,7 +63,7 @@ description = "활성화된 세션만 보려면 토글을 켜주세요."
|
||||
accept_error = "동의 처리에 실패했습니다: {error}"
|
||||
client_id = "클라이언트 ID: {id}"
|
||||
client_unknown = "알 수 없는 앱"
|
||||
description = "아래 서비스가 회원님의 계정 정보에 접근하려고 합니다.\\\\\\\\n계속 진행하려면 동의 여부를 선택해 주세요."
|
||||
description = "아래 서비스가 회원님의 계정 정보에 접근하려고 합니다.\\\\\\\\\\\\\\\\n계속 진행하려면 동의 여부를 선택해 주세요."
|
||||
load_error = "동의 정보를 불러오는데 실패했습니다: {error}"
|
||||
missing_redirect = "동의가 처리되었으나 리다이렉트 URL을 받지 못했습니다."
|
||||
redirect_notice = "동의 후 자동으로 서비스로 이동합니다."
|
||||
@@ -103,12 +103,12 @@ empty_detail = "앱을 연동하면 최근 활동과 상태가 표시됩니다."
|
||||
error = "연동 정보를 불러오지 못했습니다."
|
||||
|
||||
[msg.userfront.dashboard.approved_session]
|
||||
copy_click = "{label}: {id}\\\\\\\\n클릭하면 복사됩니다."
|
||||
copy_tap = "{label}: {id}\\\\\\\\n탭하면 복사됩니다."
|
||||
copy_click = "{label}: {id}\\\\\\\\\\\\\\\\n클릭하면 복사됩니다."
|
||||
copy_tap = "{label}: {id}\\\\\\\\\\\\\\\\n탭하면 복사됩니다."
|
||||
none = "{label} 없음"
|
||||
|
||||
[msg.userfront.dashboard.revoke]
|
||||
confirm = "{app} 앱과의 연동을 해지하시겠습니까?\\\\\\\\n해지하면 다음 로그인 시 다시 동의가 필요합니다."
|
||||
confirm = "{app} 앱과의 연동을 해지하시겠습니까?\\\\\\\\\\\\\\\\n해지하면 다음 로그인 시 다시 동의가 필요합니다."
|
||||
error = "해지 실패: {error}"
|
||||
success = "{app} 연동이 해지되었습니다."
|
||||
|
||||
@@ -125,7 +125,7 @@ recent_app = "최근 접속 앱: {app}"
|
||||
session_id = "세션 ID: {id}"
|
||||
|
||||
[msg.userfront.dashboard.sessions.revoke]
|
||||
confirm = "{target} 세션을 종료하시겠습니까?\\n대상 기기에서는 다시 로그인이 필요합니다."
|
||||
confirm = "{target} 세션을 종료하시겠습니까?\\\\n대상 기기에서는 다시 로그인이 필요합니다."
|
||||
error = "세션 종료 실패: {error}"
|
||||
success = "세션이 종료되었습니다."
|
||||
|
||||
@@ -229,7 +229,7 @@ scan_hint = "모바일 앱으로 스캔하세요"
|
||||
invalid = "문자 2개와 숫자 6자리를 입력해 주세요."
|
||||
|
||||
[msg.userfront.login.unregistered]
|
||||
body = "가입되지 않은 정보입니다.\\\\\\\\n회원가입 후 이용해 주세요."
|
||||
body = "가입되지 않은 정보입니다.\\\\\\\\\\\\\\\\n회원가입 후 이용해 주세요."
|
||||
|
||||
[msg.userfront.login.verification]
|
||||
approved = "승인되었습니다. 로그인은 요청하신 창에서 완료됩니다."
|
||||
@@ -326,12 +326,12 @@ all_hint = "필수 약관 2개를 모두 확인하고 동의하면 다음 단계
|
||||
description = "계속 진행하려면 서비스 이용 조건과 개인정보 수집·이용 항목을 확인한 뒤 동의해주세요."
|
||||
privacy_summary = "개인정보 수집 항목, 이용 목적, 보관 기준을 안내합니다."
|
||||
progress = "필수 약관 {total}개 중 {count}개 동의 완료"
|
||||
title = "서비스 이용을 위해\\\\\\\\n약관에 동의해주세요"
|
||||
title = "서비스 이용을 위해\\\\\\\\\\\\\\\\n약관에 동의해주세요"
|
||||
tos_summary = "서비스 이용 조건과 책임 범위를 확인할 수 있습니다."
|
||||
|
||||
[msg.userfront.signup.auth]
|
||||
affiliate_notice = "가족사 회원의 경우 반드시 회사 공식 이메일을 입력해주세요."
|
||||
title = "본인 확인을 위해\\\\\\\\n인증을 진행해주세요"
|
||||
title = "본인 확인을 위해\\\\\\\\\\\\\\\\n인증을 진행해주세요"
|
||||
|
||||
[msg.userfront.signup.email]
|
||||
code_mismatch = "인증코드가 일치하지 않습니다."
|
||||
@@ -347,7 +347,7 @@ lowercase_required = "소문자가 최소 1개 이상 포함되어야 합니다.
|
||||
mismatch = "비밀번호가 일치하지 않습니다."
|
||||
number_required = "숫자가 최소 1개 이상 포함되어야 합니다."
|
||||
symbol_required = "특수문자가 최소 1개 이상 포함되어야 합니다."
|
||||
title = "마지막으로\\\\\\\\n비밀번호를 설정해주세요"
|
||||
title = "마지막으로\\\\\\\\\\\\\\\\n비밀번호를 설정해주세요"
|
||||
uppercase_required = "대문자가 최소 1개 이상 포함되어야 합니다."
|
||||
|
||||
[msg.userfront.signup.password.rule]
|
||||
@@ -376,7 +376,7 @@ uppercase = "대문자"
|
||||
|
||||
[msg.userfront.signup.profile]
|
||||
affiliate_hint = "가족사 이메일 사용 시 자동으로 선택됩니다."
|
||||
title = "회원님의\\\\\\\\n소속 정보를 알려주세요"
|
||||
title = "회원님의\\\\\\\\\\\\\\\\n소속 정보를 알려주세요"
|
||||
|
||||
[msg.userfront.signup.success]
|
||||
body = "성공적으로 가입되었습니다."
|
||||
|
||||
@@ -45,10 +45,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.4.1"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -268,14 +268,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -328,18 +320,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
version: "0.12.19"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -661,26 +653,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test
|
||||
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
||||
sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.26.3"
|
||||
version: "1.30.0"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
version: "0.7.10"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
||||
sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.12"
|
||||
version: "0.6.16"
|
||||
toml:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user