@podosoft/podokit 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/add.d.ts +2 -0
- package/dist/add.js +5 -1
- package/dist/assemble.d.ts +14 -0
- package/dist/assemble.js +60 -0
- package/dist/create.d.ts +2 -0
- package/dist/create.js +7 -0
- package/dist/eject.d.ts +11 -0
- package/dist/eject.js +27 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +122 -1
- package/dist/inspect.d.ts +43 -0
- package/dist/inspect.js +82 -0
- package/dist/lockfile.d.ts +80 -0
- package/dist/lockfile.js +193 -0
- package/dist/templates/base/dot-env.example +11 -6
- package/dist/templates/fullstack-nest-svelte/README.md +2 -2
- package/dist/templates/fullstack-nest-svelte/apps/api/package.json +21 -2
- package/dist/templates/fullstack-nest-svelte/apps/api/src/app.module.ts +6 -3
- package/dist/templates/fullstack-nest-svelte/apps/api/src/common/app-exception.ts +4 -12
- package/dist/templates/fullstack-nest-svelte/apps/api/src/config/env.validation.ts +1 -1
- package/dist/templates/fullstack-nest-svelte/apps/api/src/main.ts +1 -1
- package/dist/templates/fullstack-nest-svelte/apps/api/tsconfig.json +14 -5
- package/dist/templates/fullstack-nest-svelte/apps/web/package.json +4 -3
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/api.ts +5 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/select/select-content.svelte +1 -1
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/select/select-item.svelte +1 -1
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/switch/index.ts +7 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/switch/switch.svelte +29 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/api.ts +19 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/backend-proxy.ts +44 -5
- package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/+page.svelte +8 -3
- package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/[...path]/+server.ts +12 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
- package/dist/templates/fullstack-nest-svelte/dot-env.example +10 -5
- package/dist/templates/fullstack-nest-svelte/dot-gitignore +5 -0
- package/dist/templates/fullstack-nest-svelte/infra/docker/docker-compose.yml +37 -0
- package/dist/templates/fullstack-nest-svelte/infra/docker/sms-sink.mjs +40 -0
- package/dist/templates/fullstack-nest-svelte/package.json +11 -3
- package/dist/templates/fullstack-nest-svelte/tests/README.md +15 -0
- package/dist/templates/fullstack-nest-svelte/tests/api/health.api.spec.ts +14 -0
- package/dist/templates/fullstack-nest-svelte/tests/package.json +15 -0
- package/dist/templates/fullstack-nest-svelte/tests/playwright.config.ts +25 -0
- package/dist/templates/fullstack-nest-svelte/tests/ui/smoke.ui.spec.ts +8 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/app.d.ts +26 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/hooks.server.ts +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/app-sidebar.svelte +65 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/data-table.svelte +149 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/language-switch.svelte +33 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/sidebar-user-menu.svelte +44 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/table-pagination.svelte +39 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/table-toolbar.svelte +93 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/theme-toggle.svelte +27 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/index.ts +13 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/index.ts +31 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-content.svelte +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte +22 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-item.svelte +14 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-link.svelte +42 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte +31 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next.svelte +26 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte +31 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-previous.svelte +26 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination.svelte +28 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/index.ts +34 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-close.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-content.svelte +55 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-description.svelte +17 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-header.svelte +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte +17 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-portal.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-title.svelte +17 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet.svelte +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/constants.ts +6 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/context.svelte.ts +81 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/index.ts +75 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte +24 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte +33 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte +33 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +37 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +24 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +102 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +36 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +39 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte +21 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte +53 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte +36 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte +19 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte +36 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar.svelte +108 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/user-avatar.svelte +12 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/hooks/is-mobile.svelte.ts +9 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/index.ts +27 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/messages.ts +575 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/server/guards.ts +22 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.server.ts +30 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.svelte +50 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/accept-invitation/[id]/+page.svelte +36 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/+page.svelte +45 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.server.ts +5 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.svelte +685 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.server.ts +6 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.svelte +123 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/organizations/+page.server.ts +6 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/organizations/+page.svelte +264 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.server.ts +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.svelte +156 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.server.ts +26 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.svelte +322 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.server.ts +7 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.svelte +552 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/+layout.svelte +13 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/forgot-password/+page.svelte +61 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.server.ts +14 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.svelte +181 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/reset-password/+page.svelte +51 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/signup/+page.svelte +76 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/verify-email/+page.svelte +63 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.server.ts +22 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.svelte +20 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+page.svelte +22 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/oauth2/consent/+page.svelte +54 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/audit.api.spec.ts +97 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/auth-config.api.spec.ts +80 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/auth.api.spec.ts +306 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/email.api.spec.ts +120 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/users-admin.api.spec.ts +134 -0
- package/dist/templates/modules/admin-dashboard/files/tests/helpers/accounts.ts +6 -0
- package/dist/templates/modules/admin-dashboard/files/tests/helpers/hydration.ts +9 -0
- package/dist/templates/modules/admin-dashboard/files/tests/helpers/mailpit.ts +49 -0
- package/dist/templates/modules/admin-dashboard/files/tests/helpers/sms.ts +35 -0
- package/dist/templates/modules/admin-dashboard/files/tests/helpers/totp.ts +9 -0
- package/dist/templates/modules/admin-dashboard/files/tests/playwright.config.ts +26 -0
- package/dist/templates/modules/admin-dashboard/files/tests/seed.setup.ts +40 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/account.ui.spec.ts +126 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/audit.ui.spec.ts +16 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/auth.ui.spec.ts +45 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/dashboard.ui.spec.ts +25 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/data-table.ui.spec.ts +32 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/email-admin.ui.spec.ts +60 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/email.ui.spec.ts +42 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/guards.ui.spec.ts +22 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/i18n.ui.spec.ts +13 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/oidc.ui.spec.ts +57 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/organizations.ui.spec.ts +52 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/passkey.ui.spec.ts +36 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/sessions.ui.spec.ts +22 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/settings.ui.spec.ts +34 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/sidebar.ui.spec.ts +16 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/table-toolbar.ui.spec.ts +32 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/users-crud.ui.spec.ts +145 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/users.ui.spec.ts +51 -0
- package/dist/templates/modules/admin-dashboard/module.manifest.json +47 -0
- package/dist/templates/modules/api-key-auth/module.manifest.json +3 -3
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/README.md +59 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-enabled.ts +16 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-events.ts +34 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-hook.ts +74 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-log.entity.ts +29 -8
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.controller.ts +7 -2
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.decorator.ts +23 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.interceptor.ts +38 -21
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.module.ts +2 -1
- package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.service.ts +36 -0
- package/dist/templates/modules/audit-log/files/apps/api/src/migrations/1720300000000-InitAuditLogs.ts +10 -4
- package/dist/templates/modules/audit-log/module.manifest.json +37 -8
- package/dist/templates/modules/auth/files/apps/api/src/account/account.controller.ts +85 -3
- package/dist/templates/modules/auth/files/apps/api/src/account/account.module.ts +2 -1
- package/dist/templates/modules/auth/files/apps/api/src/auth/auth-provider.ts +73 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth/auth.ts +199 -31
- package/dist/templates/modules/auth/files/apps/api/src/auth/db.ts +12 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth/feature-gate.ts +56 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth/org-permissions.ts +22 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth/permissions.ts +23 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.controller.ts +33 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.entity.ts +26 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.module.ts +12 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.service.ts +118 -0
- package/dist/templates/modules/auth/files/apps/api/src/mail/mailer.ts +65 -0
- package/dist/templates/modules/auth/files/apps/api/src/migrations/1720400000000-InitAppSettings.ts +38 -0
- package/dist/templates/modules/auth/files/apps/api/src/migrations/1720500000000-InitAuthConfig.ts +27 -0
- package/dist/templates/modules/auth/files/apps/api/src/settings/app-setting.entity.ts +16 -0
- package/dist/templates/modules/auth/files/apps/api/src/settings/flag-defaults.ts +25 -0
- package/dist/templates/modules/auth/files/apps/api/src/settings/settings.module.ts +11 -0
- package/dist/templates/modules/auth/files/apps/api/src/settings/settings.service.ts +57 -0
- package/dist/templates/modules/auth/files/apps/api/src/sms/sms.ts +23 -0
- package/dist/templates/modules/auth/module.manifest.json +54 -20
- package/dist/templates/modules/bullmq/files/apps/api/src/jobs/worker.module.ts +6 -3
- package/dist/templates/modules/bullmq/module.manifest.json +4 -4
- package/dist/templates/modules/file-upload/module.manifest.json +3 -3
- package/dist/templates/modules/job-progress/module.manifest.json +9 -9
- package/dist/templates/modules/logging/module.manifest.json +3 -3
- package/dist/templates/modules/object-storage-s3/files/infra/docker/minio.compose.yml +5 -3
- package/dist/templates/modules/object-storage-s3/module.manifest.json +5 -5
- package/dist/templates/modules/rate-limit/module.manifest.json +2 -2
- package/dist/templates/modules/redis/module.manifest.json +4 -4
- package/dist/templates/modules/sse/module.manifest.json +4 -4
- package/dist/templates/todo/README.md +2 -2
- package/dist/templates/todo/apps/api/package.json +21 -2
- package/dist/templates/todo/apps/api/src/app.module.ts +6 -3
- package/dist/templates/todo/apps/api/src/common/app-exception.ts +4 -12
- package/dist/templates/todo/apps/api/src/config/env.validation.ts +1 -1
- package/dist/templates/todo/apps/api/src/main.ts +1 -1
- package/dist/templates/todo/apps/api/tsconfig.json +14 -5
- package/dist/templates/todo/apps/web/package.json +4 -3
- package/dist/templates/todo/apps/web/src/lib/api.ts +5 -0
- package/dist/templates/todo/apps/web/src/lib/components/ui/switch/index.ts +7 -0
- package/dist/templates/todo/apps/web/src/lib/components/ui/switch/switch.svelte +29 -0
- package/dist/templates/todo/apps/web/src/lib/server/api.ts +19 -0
- package/dist/templates/todo/apps/web/src/lib/server/backend-proxy.ts +44 -5
- package/dist/templates/todo/apps/web/src/routes/+page.svelte +19 -18
- package/dist/templates/todo/apps/web/src/routes/api/[...path]/+server.ts +12 -0
- package/dist/templates/todo/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
- package/dist/templates/todo/dot-env.example +10 -5
- package/dist/templates/todo/dot-gitignore +5 -0
- package/dist/templates/todo/infra/docker/docker-compose.yml +4 -0
- package/dist/templates/todo/package.json +11 -3
- package/dist/templates/todo/tests/README.md +15 -0
- package/dist/templates/todo/tests/api/health.api.spec.ts +14 -0
- package/dist/templates/todo/tests/package.json +15 -0
- package/dist/templates/todo/tests/playwright.config.ts +25 -0
- package/dist/templates/todo/tests/ui/smoke.ui.spec.ts +8 -0
- package/dist/update.d.ts +49 -0
- package/dist/update.js +158 -0
- package/package.json +2 -2
- package/dist/templates/fullstack-nest-svelte/apps/api/test/health.e2e-spec.ts +0 -23
- package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/health/+server.ts +0 -12
- package/dist/templates/todo/apps/api/test/health.e2e-spec.ts +0 -23
- package/dist/templates/todo/apps/web/src/routes/api/health/+server.ts +0 -12
- package/dist/templates/todo/apps/web/src/routes/api/todos/+server.ts +0 -24
- package/dist/templates/todo/apps/web/src/routes/api/todos/[id]/+server.ts +0 -24
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
// Static message catalogs for the admin dashboard. Default locale is English.
|
|
2
|
+
export const LOCALES = ["en", "ko"] as const;
|
|
3
|
+
export type Locale = (typeof LOCALES)[number];
|
|
4
|
+
export const defaultLocale: Locale = "en";
|
|
5
|
+
|
|
6
|
+
export const localeNames: Record<Locale, string> = {
|
|
7
|
+
en: "English",
|
|
8
|
+
ko: "한국어",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const en = {
|
|
12
|
+
common: { appName: "Admin" },
|
|
13
|
+
landing: { title: "Welcome", subtitle: "This is your app's home page. Replace it with your own content — the admin area lives under /admin.", openAdmin: "Open admin" },
|
|
14
|
+
language: { label: "Language" },
|
|
15
|
+
toolbar: { filter: "Filter", search: "Search", searchButton: "Search", all: "All" },
|
|
16
|
+
theme: { toggle: "Toggle theme", light: "Light", dark: "Dark", system: "System" },
|
|
17
|
+
auth: {
|
|
18
|
+
signInTitle: "Sign in",
|
|
19
|
+
signInDesc: "Enter your credentials to continue.",
|
|
20
|
+
email: "Email",
|
|
21
|
+
emailOrUsername: "Email or username",
|
|
22
|
+
password: "Password",
|
|
23
|
+
forgot: "Forgot?",
|
|
24
|
+
signIn: "Sign in",
|
|
25
|
+
signingIn: "Signing in…",
|
|
26
|
+
magicLinkButton: "Email me a sign-in link",
|
|
27
|
+
passkeyButton: "Use a passkey",
|
|
28
|
+
magicLinkSent: "Check your email for a sign-in link.",
|
|
29
|
+
magicLinkNeedsEmail: "Enter your email first.",
|
|
30
|
+
otpButton: "Email me a code", otpCode: "One-time code", otpVerify: "Verify code",
|
|
31
|
+
noAccount: "No account?",
|
|
32
|
+
signUp: "Sign up",
|
|
33
|
+
signInFailed: "Sign in failed",
|
|
34
|
+
createTitle: "Create account",
|
|
35
|
+
createDesc: "Sign up to get started.",
|
|
36
|
+
name: "Name",
|
|
37
|
+
create: "Create account",
|
|
38
|
+
creating: "Creating…",
|
|
39
|
+
haveAccount: "Have an account?",
|
|
40
|
+
signUpFailed: "Sign up failed",
|
|
41
|
+
resetTitle: "Reset password",
|
|
42
|
+
resetDesc: "We'll send a reset link to your email.",
|
|
43
|
+
sendReset: "Send reset link",
|
|
44
|
+
sending: "Sending…",
|
|
45
|
+
resetSent: "If that email exists, a reset link is on its way.",
|
|
46
|
+
backToSignIn: "Back to sign in",
|
|
47
|
+
requestFailed: "Request failed",
|
|
48
|
+
newTitle: "Set a new password",
|
|
49
|
+
newPassword: "New password",
|
|
50
|
+
updatePassword: "Update password",
|
|
51
|
+
updating: "Updating…",
|
|
52
|
+
missingToken: "Missing or invalid reset token.",
|
|
53
|
+
resetFailed: "Reset failed",
|
|
54
|
+
verifyTitle: "Verify your email",
|
|
55
|
+
verifyDesc: "We sent a verification link to {email}. Open it to activate your account.",
|
|
56
|
+
verifyDescNoEmail: "Enter your email to receive a new verification link.",
|
|
57
|
+
verifySent: "Verification email sent — check your inbox.",
|
|
58
|
+
verifyLinkError: "That verification link is invalid or has expired. Request a new one below.",
|
|
59
|
+
resendVerification: "Resend verification email",
|
|
60
|
+
emailNotVerified: "Verify your email before signing in.",
|
|
61
|
+
},
|
|
62
|
+
nav: { overview: "Overview", users: "Users", sessions: "Sessions", organizations: "Organizations", audit: "Audit log", account: "Account", settings: "Settings", signOut: "Sign out" },
|
|
63
|
+
passkeys: {
|
|
64
|
+
title: "Passkeys", subtitle: "Passwordless sign-in with your device (Face ID, fingerprint, security key).",
|
|
65
|
+
name: "Name", namePlaceholder: "e.g. MacBook", add: "Add passkey", remove: "Remove", untitled: "Passkey",
|
|
66
|
+
added: "Passkey added", addFailed: "Failed to add passkey", removed: "Passkey removed", removeFailed: "Failed to remove passkey",
|
|
67
|
+
empty: "No passkeys yet.", created: "Created", total: "{count} passkeys",
|
|
68
|
+
},
|
|
69
|
+
acceptInvitation: {
|
|
70
|
+
title: "Organization invitation", pending: "Accepting your invitation…",
|
|
71
|
+
ok: "You have joined the organization.", error: "This invitation is invalid or has expired.",
|
|
72
|
+
goToOrgs: "Go to organizations",
|
|
73
|
+
},
|
|
74
|
+
organizations: {
|
|
75
|
+
title: "Organizations", subtitle: "Multi-tenant teams. Create organizations and invite members.",
|
|
76
|
+
create: "New organization", createTitle: "Create organization", name: "Name", slug: "Slug",
|
|
77
|
+
created: "Created", delete: "Delete", cancel: "Cancel", empty: "No organizations yet.", total: "{count} organizations",
|
|
78
|
+
submit: "Create", createdMsg: "Organization created", deletedMsg: "Organization deleted", actionFailed: "Action failed",
|
|
79
|
+
manage: "Manage", membersDesc: "Members and pending invitations.", members: "Members", pending: "Pending invitations",
|
|
80
|
+
parent: "Parent organization", noParent: "None (top level)", managers: "Managers", managersHint: "Existing users to add as managers (any number).",
|
|
81
|
+
inviteEmail: "Invite by email", invite: "Invite", invited: "Invitation sent", remove: "Remove", cancelInvite: "Cancel",
|
|
82
|
+
},
|
|
83
|
+
consent: {
|
|
84
|
+
title: "Authorize access", subtitle: "An application is requesting access to your account.",
|
|
85
|
+
requests: "It will be able to access:", allow: "Allow", deny: "Deny",
|
|
86
|
+
},
|
|
87
|
+
apiKeys: {
|
|
88
|
+
title: "API keys", subtitle: "Personal keys for programmatic access. Send as an x-api-key header.",
|
|
89
|
+
name: "Name", namePlaceholder: "e.g. CI pipeline", create: "Create key",
|
|
90
|
+
keyColumn: "Key", created: "Created", untitled: "Untitled", revoke: "Revoke",
|
|
91
|
+
revoked: "Key revoked", revokeFailed: "Failed to revoke key", empty: "No API keys yet.", total: "{count} API keys",
|
|
92
|
+
createdTitle: "API key created", createdDesc: "Copy it now — you will not be able to see it again.",
|
|
93
|
+
copy: "Copy", copied: "Copied to clipboard", done: "Done",
|
|
94
|
+
},
|
|
95
|
+
settings: {
|
|
96
|
+
title: "Settings", subtitle: "Which authentication features are enabled, and how they are configured.",
|
|
97
|
+
authFeaturesTitle: "Authentication features", authFeaturesSubtitle: "Toggle sign-in methods and security features. Changes apply immediately.",
|
|
98
|
+
serverConfigTitle: "Server configuration", serverConfigSubtitle: "Set through environment variables and applied at startup (read-only).",
|
|
99
|
+
enabled: "Enabled", disabled: "Disabled", configuredVia: "Configured via {env}", manage: "Manage",
|
|
100
|
+
saved: "Setting updated", saveFailed: "Failed to update setting",
|
|
101
|
+
emailPassword: "Email & password", emailPasswordDesc: "Sign in with an email address and password.",
|
|
102
|
+
emailVerification: "Email verification", emailVerificationDesc: "Require new sign-ups to confirm their address.",
|
|
103
|
+
magicLink: "Magic link", magicLinkDesc: "Passwordless sign-in via an emailed link.",
|
|
104
|
+
emailOtp: "Email one-time code", emailOtpDesc: "Passwordless sign-in with an emailed code.",
|
|
105
|
+
username: "Username sign-in", usernameDesc: "Let users sign in with a username instead of an email.",
|
|
106
|
+
multiSession: "Multi-account sessions", multiSessionDesc: "Let one browser stay signed into several accounts and switch between them.",
|
|
107
|
+
phoneNumber: "Phone number", phoneNumberDesc: "Register and verify a phone number via SMS (configure a provider for real delivery).",
|
|
108
|
+
apiKey: "API keys", apiKeyDesc: "Let users create personal API keys for programmatic access.",
|
|
109
|
+
passkey: "Passkeys", passkeyDesc: "Let users register passkeys for passwordless sign-in.",
|
|
110
|
+
organization: "Organizations", organizationDesc: "Multi-tenant organizations with members and email invitations.",
|
|
111
|
+
oidcProvider: "OIDC provider", oidcProviderDesc: "Act as an identity provider so other apps can sign in with this one.",
|
|
112
|
+
twoFactor: "Two-factor authentication", twoFactorDesc: "TOTP second factor with backup codes.",
|
|
113
|
+
socialProviders: "Social providers", socialProvidersDesc: "OAuth sign-in (Google, GitHub).",
|
|
114
|
+
breachCheck: "Breached-password check", breachCheckDesc: "Reject passwords found in known breaches (Have I Been Pwned).",
|
|
115
|
+
accountDeletion: "Account deletion", accountDeletionDesc: "Let users delete their own account.",
|
|
116
|
+
auditLog: "Audit log", auditLogDesc: "Record security-relevant actions.",
|
|
117
|
+
signInTitle: "Sign-in methods", signInSubtitle: "How users authenticate. Toggle methods on/off; social providers open a popup for credentials.",
|
|
118
|
+
emailTitle: "Email", emailSubtitle: "Outgoing mail (SMTP) and the email-verification policy.",
|
|
119
|
+
securityTitle: "Security & policy", securitySubtitle: "Second factor, breached-password rejection, account deletion, and audit logging.",
|
|
120
|
+
advancedTitle: "Advanced", advancedSubtitle: "API keys, organizations, and acting as an OIDC identity provider.",
|
|
121
|
+
socialTitle: "Social login", socialSubtitle: "Paste OAuth credentials to enable sign-in with a provider. Applied immediately — no restart. Secrets are stored encrypted.",
|
|
122
|
+
smtpTitle: "SMTP (email delivery)", smtpSubtitle: "Outgoing mail for sign-in links, verification, and invitations. Applied immediately.",
|
|
123
|
+
google: "Google", github: "GitHub",
|
|
124
|
+
clientId: "Client ID", clientSecret: "Client secret", redirectUri: "Redirect URI", secretSet: "•••••••• (saved — leave blank to keep)",
|
|
125
|
+
save: "Save", cancel: "Cancel", configure: "Configure", notConfigured: "Not configured", configuredOff: "Configured (off)",
|
|
126
|
+
socialDialogDesc: "Paste the OAuth client ID and secret from the provider's console, then enable it. Applied immediately.",
|
|
127
|
+
smtpEnabled: "Enabled", smtpHost: "Host", smtpPort: "Port", smtpUser: "Username", smtpPass: "Password", smtpFrom: "From address", smtpSecure: "TLS (secure)",
|
|
128
|
+
addProvider: "Add provider", provider: "Provider", remove: "Remove", smtpConfigure: "SMTP settings",
|
|
129
|
+
edit: "Edit", close: "Close", back: "Back", noProviders: "No providers added yet.",
|
|
130
|
+
socialCardDesc: "Sign in with Google, GitHub, Apple and other OAuth providers.",
|
|
131
|
+
},
|
|
132
|
+
dashboard: { title: "Dashboard", welcome: "Welcome back, {name}.", yourRole: "Your role", signedInAs: "Signed in as", unverifiedUsers: "Unverified users" },
|
|
133
|
+
audit: { title: "Audit log", when: "When", actor: "Actor", action: "Action", target: "Target", ip: "IP", empty: "No audit entries.", loadFailed: "Failed to load audit log", total: "{count} entries", searchField: "Actor or target" },
|
|
134
|
+
users: {
|
|
135
|
+
title: "Users",
|
|
136
|
+
search: "Search by email…",
|
|
137
|
+
name: "Name",
|
|
138
|
+
email: "Email",
|
|
139
|
+
role: "Role",
|
|
140
|
+
status: "Status",
|
|
141
|
+
active: "Active",
|
|
142
|
+
banned: "Banned",
|
|
143
|
+
makeUser: "Make user",
|
|
144
|
+
makeAdmin: "Make admin",
|
|
145
|
+
ban: "Ban",
|
|
146
|
+
unban: "Unban",
|
|
147
|
+
empty: "No users.",
|
|
148
|
+
total: "{count} users",
|
|
149
|
+
previous: "Previous",
|
|
150
|
+
next: "Next",
|
|
151
|
+
roleSet: "Role set to {role}",
|
|
152
|
+
userBanned: "User banned",
|
|
153
|
+
userUnbanned: "User unbanned",
|
|
154
|
+
loadFailed: "Failed to load users",
|
|
155
|
+
actionFailed: "Action failed",
|
|
156
|
+
addUser: "Add user",
|
|
157
|
+
createTitle: "Create user",
|
|
158
|
+
password: "Password",
|
|
159
|
+
create: "Create",
|
|
160
|
+
cancel: "Cancel",
|
|
161
|
+
close: "Close",
|
|
162
|
+
roleAdmin: "Admin",
|
|
163
|
+
roleUser: "User",
|
|
164
|
+
roleModerator: "Moderator",
|
|
165
|
+
userCreated: "User created",
|
|
166
|
+
setPassword: "Set password",
|
|
167
|
+
newPassword: "New password",
|
|
168
|
+
save: "Save",
|
|
169
|
+
passwordSet: "Password updated",
|
|
170
|
+
delete: "Delete",
|
|
171
|
+
deleteTitle: "Delete user",
|
|
172
|
+
deleteConfirm: "Delete {email}? This cannot be undone.",
|
|
173
|
+
userDeleted: "User deleted",
|
|
174
|
+
confirmPassword: "Confirm password",
|
|
175
|
+
confirmNewPassword: "Confirm new password",
|
|
176
|
+
passwordMismatch: "Passwords do not match",
|
|
177
|
+
edit: "Edit",
|
|
178
|
+
editTitle: "Edit user",
|
|
179
|
+
userUpdated: "User updated",
|
|
180
|
+
impersonate: "Impersonate",
|
|
181
|
+
banTitle: "Ban user",
|
|
182
|
+
banReason: "Reason (optional)",
|
|
183
|
+
banExpiryDays: "Expires in (days, optional)",
|
|
184
|
+
banExpiry: "Ban expires",
|
|
185
|
+
banPermanent: "Permanent ban",
|
|
186
|
+
joined: "Joined",
|
|
187
|
+
stopImpersonating: "Stop impersonating",
|
|
188
|
+
impersonatingAs: "Impersonating {email}",
|
|
189
|
+
manage: "Manage",
|
|
190
|
+
revokeSession: "Revoke",
|
|
191
|
+
verified: "Verified",
|
|
192
|
+
unverified: "Unverified",
|
|
193
|
+
sendVerification: "Send verification email",
|
|
194
|
+
verificationSent: "Verification email sent",
|
|
195
|
+
markVerified: "Mark verified",
|
|
196
|
+
markedVerified: "Marked as verified",
|
|
197
|
+
sendResetEmail: "Send password reset email",
|
|
198
|
+
resetEmailSent: "Password reset email sent",
|
|
199
|
+
sendVerificationOnCreate: "Send verification email",
|
|
200
|
+
},
|
|
201
|
+
sessions: {
|
|
202
|
+
title: "Active sessions",
|
|
203
|
+
device: "Device",
|
|
204
|
+
ip: "IP",
|
|
205
|
+
since: "Since",
|
|
206
|
+
revoke: "Revoke",
|
|
207
|
+
unknown: "Unknown",
|
|
208
|
+
empty: "No active sessions.",
|
|
209
|
+
revoked: "Session revoked",
|
|
210
|
+
loadFailed: "Failed to load sessions",
|
|
211
|
+
revokeFailed: "Failed to revoke",
|
|
212
|
+
status: "Status",
|
|
213
|
+
current: "Current",
|
|
214
|
+
signOutOthers: "Sign out other sessions",
|
|
215
|
+
accountsTitle: "Signed-in accounts", switchAccount: "Switch", switchFailed: "Failed to switch account",
|
|
216
|
+
othersRevoked: "Signed out other sessions",
|
|
217
|
+
total: "{count} sessions",
|
|
218
|
+
},
|
|
219
|
+
adminSessions: {
|
|
220
|
+
title: "User sessions",
|
|
221
|
+
user: "User",
|
|
222
|
+
device: "Device",
|
|
223
|
+
ip: "IP",
|
|
224
|
+
since: "Since",
|
|
225
|
+
expires: "Expires",
|
|
226
|
+
impersonated: "Impersonated",
|
|
227
|
+
revoke: "Revoke session",
|
|
228
|
+
revokeAll: "Revoke all for user",
|
|
229
|
+
unknown: "Unknown",
|
|
230
|
+
empty: "No active sessions.",
|
|
231
|
+
revoked: "Session revoked",
|
|
232
|
+
allRevoked: "All sessions revoked for user",
|
|
233
|
+
loadFailed: "Failed to load sessions",
|
|
234
|
+
total: "{count} sessions",
|
|
235
|
+
},
|
|
236
|
+
account: {
|
|
237
|
+
title: "Account",
|
|
238
|
+
profile: "Profile",
|
|
239
|
+
name: "Name",
|
|
240
|
+
username: "Username",
|
|
241
|
+
phone: "Phone number", phoneCode: "Verification code", phoneSendCode: "Send code", phoneVerify: "Verify", phoneCodeSent: "Code sent", phoneVerified: "Phone verified",
|
|
242
|
+
email: "Email",
|
|
243
|
+
role: "Role",
|
|
244
|
+
changePassword: "Change password",
|
|
245
|
+
currentPassword: "Current password",
|
|
246
|
+
newPassword: "New password",
|
|
247
|
+
update: "Update password",
|
|
248
|
+
updating: "Updating…",
|
|
249
|
+
changed: "Password changed",
|
|
250
|
+
changeFailed: "Failed to change password",
|
|
251
|
+
nav: { profile: "Profile", security: "Security", connected: "Connected", sessions: "Sessions", apiKeys: "API keys", danger: "Danger zone" },
|
|
252
|
+
twoFactorTitle: "Two-factor authentication",
|
|
253
|
+
twoFactorDesc: "Add a one-time code from your authenticator app at sign-in.",
|
|
254
|
+
twoFactorOn: "Enabled",
|
|
255
|
+
twoFactorOff: "Disabled",
|
|
256
|
+
enable: "Enable",
|
|
257
|
+
disable: "Disable",
|
|
258
|
+
password: "Password",
|
|
259
|
+
scanHint: "Add this to your authenticator app, then enter the 6-digit code.",
|
|
260
|
+
setupKey: "Setup key (otpauth URI)",
|
|
261
|
+
backupCodes: "Backup codes — store them somewhere safe",
|
|
262
|
+
code: "Verification code",
|
|
263
|
+
verify: "Verify",
|
|
264
|
+
twoFactorEnabled: "Two-factor enabled",
|
|
265
|
+
twoFactorDisabled: "Two-factor disabled",
|
|
266
|
+
connectedTitle: "Connected accounts",
|
|
267
|
+
connectedDesc: "Link social accounts to sign in with them.",
|
|
268
|
+
connect: "Connect",
|
|
269
|
+
disconnect: "Disconnect",
|
|
270
|
+
connected: "Connected",
|
|
271
|
+
notConnected: "Not connected",
|
|
272
|
+
disconnected: "Disconnected",
|
|
273
|
+
dangerTitle: "Delete account",
|
|
274
|
+
dangerDesc: "Permanently delete your account and all associated data.",
|
|
275
|
+
deleteAccount: "Delete account",
|
|
276
|
+
deleteAccountConfirm: "This permanently deletes your account and cannot be undone. Enter your password to confirm.",
|
|
277
|
+
accountDeleted: "Account deleted",
|
|
278
|
+
save: "Save changes",
|
|
279
|
+
saved: "Profile updated",
|
|
280
|
+
saveFailed: "Failed to save profile",
|
|
281
|
+
saving: "Saving…",
|
|
282
|
+
changeEmail: "Change email",
|
|
283
|
+
emailChanged: "Email address updated",
|
|
284
|
+
emailChangePending: "Check your current inbox to approve the change",
|
|
285
|
+
verified: "Verified",
|
|
286
|
+
unverified: "Unverified",
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export type Messages = typeof en;
|
|
291
|
+
|
|
292
|
+
const ko: Messages = {
|
|
293
|
+
common: { appName: "관리자" },
|
|
294
|
+
landing: { title: "환영합니다", subtitle: "앱의 홈 페이지입니다. 원하는 내용으로 교체하세요 — 관리자 기능은 /admin 에 있습니다.", openAdmin: "관리자 열기" },
|
|
295
|
+
language: { label: "언어" },
|
|
296
|
+
toolbar: { filter: "필터", search: "검색", searchButton: "검색", all: "전체" },
|
|
297
|
+
theme: { toggle: "테마 전환", light: "라이트", dark: "다크", system: "시스템" },
|
|
298
|
+
auth: {
|
|
299
|
+
signInTitle: "로그인",
|
|
300
|
+
signInDesc: "계속하려면 로그인하세요.",
|
|
301
|
+
email: "이메일",
|
|
302
|
+
emailOrUsername: "이메일 또는 사용자명",
|
|
303
|
+
password: "비밀번호",
|
|
304
|
+
forgot: "비밀번호 찾기",
|
|
305
|
+
signIn: "로그인",
|
|
306
|
+
signingIn: "로그인 중…",
|
|
307
|
+
magicLinkButton: "로그인 링크 이메일로 받기",
|
|
308
|
+
passkeyButton: "패스키 사용",
|
|
309
|
+
magicLinkSent: "이메일의 로그인 링크를 확인하세요.",
|
|
310
|
+
magicLinkNeedsEmail: "먼저 이메일을 입력하세요.",
|
|
311
|
+
otpButton: "코드 이메일로 받기", otpCode: "일회용 코드", otpVerify: "코드 확인",
|
|
312
|
+
noAccount: "계정이 없으신가요?",
|
|
313
|
+
signUp: "회원가입",
|
|
314
|
+
signInFailed: "로그인에 실패했습니다",
|
|
315
|
+
createTitle: "회원가입",
|
|
316
|
+
createDesc: "가입하고 시작하세요.",
|
|
317
|
+
name: "이름",
|
|
318
|
+
create: "계정 만들기",
|
|
319
|
+
creating: "생성 중…",
|
|
320
|
+
haveAccount: "이미 계정이 있으신가요?",
|
|
321
|
+
signUpFailed: "회원가입에 실패했습니다",
|
|
322
|
+
resetTitle: "비밀번호 재설정",
|
|
323
|
+
resetDesc: "이메일로 재설정 링크를 보내드립니다.",
|
|
324
|
+
sendReset: "재설정 링크 보내기",
|
|
325
|
+
sending: "전송 중…",
|
|
326
|
+
resetSent: "해당 이메일이 존재하면 재설정 링크가 전송됩니다.",
|
|
327
|
+
backToSignIn: "로그인으로 돌아가기",
|
|
328
|
+
requestFailed: "요청에 실패했습니다",
|
|
329
|
+
newTitle: "새 비밀번호 설정",
|
|
330
|
+
newPassword: "새 비밀번호",
|
|
331
|
+
updatePassword: "비밀번호 변경",
|
|
332
|
+
updating: "변경 중…",
|
|
333
|
+
missingToken: "재설정 토큰이 없거나 유효하지 않습니다.",
|
|
334
|
+
verifyTitle: "이메일 인증",
|
|
335
|
+
verifyDesc: "{email} 주소로 인증 링크를 보냈습니다. 링크를 열어 계정을 활성화하세요.",
|
|
336
|
+
verifyDescNoEmail: "새 인증 링크를 받을 이메일을 입력하세요.",
|
|
337
|
+
verifySent: "인증 메일을 보냈습니다 — 받은편지함을 확인하세요.",
|
|
338
|
+
verifyLinkError: "인증 링크가 유효하지 않거나 만료되었습니다. 아래에서 다시 요청하세요.",
|
|
339
|
+
resendVerification: "인증 메일 다시 보내기",
|
|
340
|
+
emailNotVerified: "로그인 전에 이메일을 인증해 주세요.",
|
|
341
|
+
resetFailed: "재설정에 실패했습니다",
|
|
342
|
+
},
|
|
343
|
+
nav: { overview: "개요", users: "회원", sessions: "세션", organizations: "조직", audit: "감사 로그", account: "계정", settings: "설정", signOut: "로그아웃" },
|
|
344
|
+
passkeys: {
|
|
345
|
+
title: "패스키", subtitle: "기기로 비밀번호 없이 로그인(Face ID, 지문, 보안 키).",
|
|
346
|
+
name: "이름", namePlaceholder: "예: MacBook", add: "패스키 추가", remove: "삭제", untitled: "패스키",
|
|
347
|
+
added: "패스키를 추가했습니다", addFailed: "패스키 추가에 실패했습니다", removed: "패스키를 삭제했습니다", removeFailed: "패스키 삭제에 실패했습니다",
|
|
348
|
+
empty: "아직 패스키가 없습니다.", created: "생성일", total: "패스키 {count}개",
|
|
349
|
+
},
|
|
350
|
+
acceptInvitation: {
|
|
351
|
+
title: "조직 초대", pending: "초대를 수락하는 중…",
|
|
352
|
+
ok: "조직에 합류했습니다.", error: "유효하지 않거나 만료된 초대입니다.",
|
|
353
|
+
goToOrgs: "조직으로 이동",
|
|
354
|
+
},
|
|
355
|
+
organizations: {
|
|
356
|
+
title: "조직", subtitle: "멀티테넌트 팀. 조직을 만들고 멤버를 초대합니다.",
|
|
357
|
+
create: "새 조직", createTitle: "조직 만들기", name: "이름", slug: "슬러그",
|
|
358
|
+
created: "생성일", delete: "삭제", cancel: "취소", empty: "아직 조직이 없습니다.", total: "조직 {count}개",
|
|
359
|
+
submit: "만들기", createdMsg: "조직을 만들었습니다", deletedMsg: "조직을 삭제했습니다", actionFailed: "작업에 실패했습니다",
|
|
360
|
+
manage: "관리", membersDesc: "멤버와 대기 중인 초대.", members: "멤버", pending: "대기 중 초대",
|
|
361
|
+
parent: "상위 조직", noParent: "없음(최상위)", managers: "매니저", managersHint: "매니저로 추가할 기존 사용자(여러 명 가능).",
|
|
362
|
+
inviteEmail: "이메일로 초대", invite: "초대", invited: "초대를 보냈습니다", remove: "제거", cancelInvite: "취소",
|
|
363
|
+
},
|
|
364
|
+
consent: {
|
|
365
|
+
title: "접근 승인", subtitle: "한 애플리케이션이 계정 접근을 요청합니다.",
|
|
366
|
+
requests: "접근 가능 범위:", allow: "허용", deny: "거부",
|
|
367
|
+
},
|
|
368
|
+
apiKeys: {
|
|
369
|
+
title: "API 키", subtitle: "프로그래밍 방식 접근용 개인 키. x-api-key 헤더로 전송합니다.",
|
|
370
|
+
name: "이름", namePlaceholder: "예: CI 파이프라인", create: "키 생성",
|
|
371
|
+
keyColumn: "키", created: "생성일", untitled: "제목 없음", revoke: "폐기",
|
|
372
|
+
revoked: "키를 폐기했습니다", revokeFailed: "키 폐기에 실패했습니다", empty: "아직 API 키가 없습니다.", total: "API 키 {count}개",
|
|
373
|
+
createdTitle: "API 키 생성됨", createdDesc: "지금 복사하세요 — 다시 볼 수 없습니다.",
|
|
374
|
+
copy: "복사", copied: "클립보드에 복사됨", done: "완료",
|
|
375
|
+
},
|
|
376
|
+
settings: {
|
|
377
|
+
title: "설정", subtitle: "활성화된 인증 기능과 구성 방법입니다.",
|
|
378
|
+
authFeaturesTitle: "인증 기능", authFeaturesSubtitle: "로그인 수단과 보안 기능을 켜고 끕니다. 변경은 즉시 적용됩니다.",
|
|
379
|
+
serverConfigTitle: "서버 구성", serverConfigSubtitle: "환경변수로 설정되어 시작 시 적용됩니다(읽기 전용).",
|
|
380
|
+
enabled: "활성", disabled: "비활성", configuredVia: "{env} 로 구성", manage: "관리",
|
|
381
|
+
saved: "설정을 변경했습니다", saveFailed: "설정 변경에 실패했습니다",
|
|
382
|
+
emailPassword: "이메일·비밀번호", emailPasswordDesc: "이메일과 비밀번호로 로그인.",
|
|
383
|
+
emailVerification: "이메일 인증", emailVerificationDesc: "신규 가입 시 이메일 확인 요구.",
|
|
384
|
+
magicLink: "매직 링크", magicLinkDesc: "이메일 링크로 비밀번호 없이 로그인.",
|
|
385
|
+
emailOtp: "이메일 일회용 코드", emailOtpDesc: "이메일로 받은 코드로 비밀번호 없이 로그인.",
|
|
386
|
+
username: "사용자명 로그인", usernameDesc: "이메일 대신 사용자명으로 로그인.",
|
|
387
|
+
multiSession: "다중 계정 세션", multiSessionDesc: "한 브라우저에서 여러 계정에 로그인하고 전환.",
|
|
388
|
+
phoneNumber: "전화번호", phoneNumberDesc: "SMS로 전화번호 등록·인증(실발송은 프로바이더 연동 필요).",
|
|
389
|
+
apiKey: "API 키", apiKeyDesc: "프로그래밍 방식 접근을 위한 개인 API 키 발급을 허용.",
|
|
390
|
+
passkey: "패스키", passkeyDesc: "비밀번호 없는 로그인을 위한 패스키 등록을 허용.",
|
|
391
|
+
organization: "조직", organizationDesc: "멤버와 이메일 초대를 갖춘 멀티테넌트 조직.",
|
|
392
|
+
oidcProvider: "OIDC 제공자", oidcProviderDesc: "다른 앱이 이 앱으로 로그인하도록 신원 제공자 역할.",
|
|
393
|
+
twoFactor: "2단계 인증", twoFactorDesc: "TOTP 2차 인증 + 백업 코드.",
|
|
394
|
+
socialProviders: "소셜 로그인", socialProvidersDesc: "OAuth 로그인 (Google, GitHub).",
|
|
395
|
+
breachCheck: "유출 비밀번호 검사", breachCheckDesc: "유출된 비밀번호 거부 (Have I Been Pwned).",
|
|
396
|
+
accountDeletion: "계정 삭제", accountDeletionDesc: "사용자가 자신의 계정을 삭제.",
|
|
397
|
+
auditLog: "감사 로그", auditLogDesc: "보안 관련 동작 기록.",
|
|
398
|
+
signInTitle: "로그인 수단", signInSubtitle: "사용자가 인증하는 방법. 각 수단을 켜고 끄며, 소셜 로그인은 팝업에서 자격증명을 입력합니다.",
|
|
399
|
+
emailTitle: "이메일", emailSubtitle: "메일 발송(SMTP) 설정과 이메일 인증 정책.",
|
|
400
|
+
securityTitle: "보안·정책", securitySubtitle: "2단계 인증, 유출 비밀번호 거부, 계정 삭제, 감사 로그.",
|
|
401
|
+
advancedTitle: "고급", advancedSubtitle: "API 키, 조직, OIDC 공급자(자체 IdP) 역할.",
|
|
402
|
+
socialTitle: "소셜 로그인", socialSubtitle: "OAuth 자격증명을 붙여넣으면 해당 provider 로그인이 켜집니다. 재시작 없이 즉시 적용되며, 비밀은 암호화 저장됩니다.",
|
|
403
|
+
smtpTitle: "SMTP(이메일 발송)", smtpSubtitle: "로그인 링크·인증·초대 발송용. 즉시 적용됩니다.",
|
|
404
|
+
google: "Google", github: "GitHub",
|
|
405
|
+
clientId: "Client ID", clientSecret: "Client secret", redirectUri: "Redirect URI", secretSet: "•••••••• (저장됨 — 비우면 유지)",
|
|
406
|
+
save: "저장", cancel: "취소", configure: "설정", notConfigured: "미설정", configuredOff: "설정됨(꺼짐)",
|
|
407
|
+
socialDialogDesc: "provider 콘솔의 OAuth client ID와 secret을 붙여넣고 사용을 켜세요. 즉시 적용됩니다.",
|
|
408
|
+
smtpEnabled: "사용", smtpHost: "호스트", smtpPort: "포트", smtpUser: "사용자", smtpPass: "비밀번호", smtpFrom: "발신 주소", smtpSecure: "TLS(보안)",
|
|
409
|
+
addProvider: "공급자 추가", provider: "공급자", remove: "삭제", smtpConfigure: "SMTP 설정",
|
|
410
|
+
edit: "편집", close: "닫기", back: "뒤로", noProviders: "아직 추가된 공급자가 없습니다.",
|
|
411
|
+
socialCardDesc: "Google, GitHub, Apple 등 OAuth 공급자로 로그인.",
|
|
412
|
+
},
|
|
413
|
+
dashboard: { title: "대시보드", welcome: "{name}님, 환영합니다.", yourRole: "내 권한", signedInAs: "로그인 계정", unverifiedUsers: "미인증 사용자" },
|
|
414
|
+
audit: { title: "감사 로그", when: "시각", actor: "수행자", action: "동작", target: "대상", ip: "IP", empty: "감사 기록이 없습니다.", loadFailed: "감사 로그를 불러오지 못했습니다", total: "항목 {count}개", searchField: "수행자·대상" },
|
|
415
|
+
users: {
|
|
416
|
+
title: "회원",
|
|
417
|
+
search: "이메일로 검색…",
|
|
418
|
+
name: "이름",
|
|
419
|
+
email: "이메일",
|
|
420
|
+
role: "권한",
|
|
421
|
+
status: "상태",
|
|
422
|
+
active: "활성",
|
|
423
|
+
banned: "차단됨",
|
|
424
|
+
makeUser: "일반 사용자로",
|
|
425
|
+
makeAdmin: "관리자로",
|
|
426
|
+
ban: "차단",
|
|
427
|
+
unban: "차단 해제",
|
|
428
|
+
empty: "회원이 없습니다.",
|
|
429
|
+
total: "회원 {count}명",
|
|
430
|
+
previous: "이전",
|
|
431
|
+
next: "다음",
|
|
432
|
+
roleSet: "권한을 {role}(으)로 변경했습니다",
|
|
433
|
+
userBanned: "회원을 차단했습니다",
|
|
434
|
+
userUnbanned: "차단을 해제했습니다",
|
|
435
|
+
loadFailed: "회원 목록을 불러오지 못했습니다",
|
|
436
|
+
actionFailed: "작업에 실패했습니다",
|
|
437
|
+
addUser: "사용자 추가",
|
|
438
|
+
createTitle: "사용자 생성",
|
|
439
|
+
password: "비밀번호",
|
|
440
|
+
create: "생성",
|
|
441
|
+
cancel: "취소",
|
|
442
|
+
close: "닫기",
|
|
443
|
+
roleAdmin: "관리자",
|
|
444
|
+
roleUser: "사용자",
|
|
445
|
+
roleModerator: "중재자",
|
|
446
|
+
userCreated: "사용자를 생성했습니다",
|
|
447
|
+
setPassword: "비밀번호 설정",
|
|
448
|
+
newPassword: "새 비밀번호",
|
|
449
|
+
save: "저장",
|
|
450
|
+
passwordSet: "비밀번호를 변경했습니다",
|
|
451
|
+
delete: "삭제",
|
|
452
|
+
deleteTitle: "사용자 삭제",
|
|
453
|
+
deleteConfirm: "{email} 사용자를 삭제할까요? 되돌릴 수 없습니다.",
|
|
454
|
+
userDeleted: "사용자를 삭제했습니다",
|
|
455
|
+
confirmPassword: "비밀번호 확인",
|
|
456
|
+
confirmNewPassword: "새 비밀번호 확인",
|
|
457
|
+
passwordMismatch: "비밀번호가 일치하지 않습니다",
|
|
458
|
+
edit: "편집",
|
|
459
|
+
editTitle: "사용자 편집",
|
|
460
|
+
userUpdated: "사용자를 수정했습니다",
|
|
461
|
+
impersonate: "이 사용자로 로그인",
|
|
462
|
+
banTitle: "사용자 차단",
|
|
463
|
+
banReason: "사유 (선택)",
|
|
464
|
+
banExpiryDays: "만료 (일, 선택)",
|
|
465
|
+
banExpiry: "차단 만료",
|
|
466
|
+
banPermanent: "영구 차단",
|
|
467
|
+
joined: "가입일",
|
|
468
|
+
stopImpersonating: "대리 로그인 종료",
|
|
469
|
+
impersonatingAs: "{email} 사용자로 대리 로그인 중",
|
|
470
|
+
manage: "관리",
|
|
471
|
+
revokeSession: "종료",
|
|
472
|
+
verified: "인증됨",
|
|
473
|
+
unverified: "미인증",
|
|
474
|
+
sendVerification: "인증 메일 보내기",
|
|
475
|
+
verificationSent: "인증 메일을 보냈습니다",
|
|
476
|
+
markVerified: "인증됨으로 표시",
|
|
477
|
+
markedVerified: "인증 처리했습니다",
|
|
478
|
+
sendResetEmail: "비밀번호 재설정 메일 보내기",
|
|
479
|
+
resetEmailSent: "재설정 메일을 보냈습니다",
|
|
480
|
+
sendVerificationOnCreate: "인증 메일 보내기",
|
|
481
|
+
},
|
|
482
|
+
sessions: {
|
|
483
|
+
title: "활성 세션",
|
|
484
|
+
device: "기기",
|
|
485
|
+
ip: "IP",
|
|
486
|
+
since: "시작",
|
|
487
|
+
revoke: "종료",
|
|
488
|
+
unknown: "알 수 없음",
|
|
489
|
+
empty: "활성 세션이 없습니다.",
|
|
490
|
+
revoked: "세션을 종료했습니다",
|
|
491
|
+
loadFailed: "세션을 불러오지 못했습니다",
|
|
492
|
+
revokeFailed: "세션 종료에 실패했습니다",
|
|
493
|
+
status: "상태",
|
|
494
|
+
current: "현재",
|
|
495
|
+
signOutOthers: "다른 세션 모두 종료",
|
|
496
|
+
accountsTitle: "로그인된 계정", switchAccount: "전환", switchFailed: "계정 전환에 실패했습니다",
|
|
497
|
+
othersRevoked: "다른 세션을 모두 종료했습니다",
|
|
498
|
+
total: "세션 {count}개",
|
|
499
|
+
},
|
|
500
|
+
adminSessions: {
|
|
501
|
+
title: "사용자 세션",
|
|
502
|
+
user: "사용자",
|
|
503
|
+
device: "기기",
|
|
504
|
+
ip: "IP",
|
|
505
|
+
since: "시작",
|
|
506
|
+
expires: "만료",
|
|
507
|
+
impersonated: "임퍼스네이트",
|
|
508
|
+
revoke: "세션 종료",
|
|
509
|
+
revokeAll: "사용자 세션 모두 종료",
|
|
510
|
+
unknown: "알 수 없음",
|
|
511
|
+
empty: "활성 세션이 없습니다.",
|
|
512
|
+
revoked: "세션을 종료했습니다",
|
|
513
|
+
allRevoked: "사용자의 세션을 모두 종료했습니다",
|
|
514
|
+
loadFailed: "세션을 불러오지 못했습니다",
|
|
515
|
+
total: "세션 {count}개",
|
|
516
|
+
},
|
|
517
|
+
account: {
|
|
518
|
+
title: "계정",
|
|
519
|
+
profile: "프로필",
|
|
520
|
+
name: "이름",
|
|
521
|
+
username: "사용자명",
|
|
522
|
+
phone: "전화번호", phoneCode: "인증 코드", phoneSendCode: "코드 전송", phoneVerify: "인증", phoneCodeSent: "코드를 전송했습니다", phoneVerified: "전화번호 인증됨",
|
|
523
|
+
email: "이메일",
|
|
524
|
+
role: "권한",
|
|
525
|
+
changePassword: "비밀번호 변경",
|
|
526
|
+
currentPassword: "현재 비밀번호",
|
|
527
|
+
newPassword: "새 비밀번호",
|
|
528
|
+
update: "비밀번호 변경",
|
|
529
|
+
updating: "변경 중…",
|
|
530
|
+
changed: "비밀번호를 변경했습니다",
|
|
531
|
+
changeFailed: "비밀번호 변경에 실패했습니다",
|
|
532
|
+
nav: { profile: "프로필", security: "보안", connected: "연결", sessions: "세션", apiKeys: "API 키", danger: "위험 영역" },
|
|
533
|
+
twoFactorTitle: "2단계 인증",
|
|
534
|
+
twoFactorDesc: "로그인 시 인증 앱의 일회용 코드를 추가로 요구합니다.",
|
|
535
|
+
twoFactorOn: "사용 중",
|
|
536
|
+
twoFactorOff: "사용 안 함",
|
|
537
|
+
enable: "사용",
|
|
538
|
+
disable: "해제",
|
|
539
|
+
password: "비밀번호",
|
|
540
|
+
scanHint: "인증 앱에 등록한 뒤 6자리 코드를 입력하세요.",
|
|
541
|
+
setupKey: "설정 키 (otpauth URI)",
|
|
542
|
+
backupCodes: "백업 코드 — 안전한 곳에 보관하세요",
|
|
543
|
+
code: "인증 코드",
|
|
544
|
+
verify: "확인",
|
|
545
|
+
twoFactorEnabled: "2단계 인증을 사용합니다",
|
|
546
|
+
twoFactorDisabled: "2단계 인증을 해제했습니다",
|
|
547
|
+
connectedTitle: "연결된 계정",
|
|
548
|
+
connectedDesc: "소셜 계정을 연결하면 해당 계정으로 로그인할 수 있습니다.",
|
|
549
|
+
connect: "연결",
|
|
550
|
+
disconnect: "연결 해제",
|
|
551
|
+
connected: "연결됨",
|
|
552
|
+
notConnected: "연결 안 됨",
|
|
553
|
+
disconnected: "연결을 해제했습니다",
|
|
554
|
+
dangerTitle: "계정 삭제",
|
|
555
|
+
dangerDesc: "계정과 모든 관련 데이터를 영구히 삭제합니다.",
|
|
556
|
+
deleteAccount: "계정 삭제",
|
|
557
|
+
deleteAccountConfirm: "계정이 영구히 삭제되며 되돌릴 수 없습니다. 확인하려면 비밀번호를 입력하세요.",
|
|
558
|
+
accountDeleted: "계정을 삭제했습니다",
|
|
559
|
+
save: "변경 저장",
|
|
560
|
+
saved: "프로필을 저장했습니다",
|
|
561
|
+
saveFailed: "프로필 저장에 실패했습니다",
|
|
562
|
+
saving: "저장 중…",
|
|
563
|
+
changeEmail: "이메일 변경",
|
|
564
|
+
emailChanged: "이메일 주소를 변경했습니다",
|
|
565
|
+
emailChangePending: "현재 메일함에서 변경을 승인해 주세요",
|
|
566
|
+
verified: "인증됨",
|
|
567
|
+
unverified: "미인증",
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
export const messages: Record<Locale, Messages> = { en, ko };
|
|
572
|
+
|
|
573
|
+
export function resolveLocale(value: string | undefined | null): Locale {
|
|
574
|
+
return LOCALES.includes(value as Locale) ? (value as Locale) : defaultLocale;
|
|
575
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { error } from "@sveltejs/kit";
|
|
2
|
+
|
|
3
|
+
/** Roles that may reach the admin console. Kept as a set so custom roles can be
|
|
4
|
+
* added here (and, later, replaced by a permission check) without touching every
|
|
5
|
+
* page loader. better-auth stores a user's role(s) as a comma-separated string. */
|
|
6
|
+
const ADMIN_ROLES = ["admin"];
|
|
7
|
+
|
|
8
|
+
type WithRole = { role?: string | null } | null | undefined;
|
|
9
|
+
|
|
10
|
+
/** True when the user holds at least one admin role. */
|
|
11
|
+
export function isAdmin(user: WithRole): boolean {
|
|
12
|
+
const roles = (user?.role ?? "")
|
|
13
|
+
.split(",")
|
|
14
|
+
.map((r) => r.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
return roles.some((r) => ADMIN_ROLES.includes(r));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Guard an admin-only loader: throws 403 unless the user holds an admin role. */
|
|
20
|
+
export function requireAdmin(user: WithRole): void {
|
|
21
|
+
if (!isAdmin(user)) error(403, "Admins only");
|
|
22
|
+
}
|
package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.server.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LayoutServerLoad } from "./$types";
|
|
2
|
+
import type { Capabilities } from "@podosoft/podokit-api-client";
|
|
3
|
+
|
|
4
|
+
export const load: LayoutServerLoad = async ({ locals, fetch }) => {
|
|
5
|
+
let capabilities: Capabilities = {
|
|
6
|
+
twoFactor: false,
|
|
7
|
+
providers: [],
|
|
8
|
+
deleteAccount: false,
|
|
9
|
+
auditLog: false,
|
|
10
|
+
emailVerification: false,
|
|
11
|
+
passwordBreachCheck: false,
|
|
12
|
+
magicLink: false,
|
|
13
|
+
emailOtp: false,
|
|
14
|
+
username: false,
|
|
15
|
+
multiSession: false,
|
|
16
|
+
phoneNumber: false,
|
|
17
|
+
apiKey: false,
|
|
18
|
+
passkey: false,
|
|
19
|
+
organization: false,
|
|
20
|
+
oidcProvider: false,
|
|
21
|
+
roles: ["admin", "user"],
|
|
22
|
+
};
|
|
23
|
+
try {
|
|
24
|
+
const res = await fetch("/api/account/capabilities");
|
|
25
|
+
if (res.ok) capabilities = (await res.json()) as Capabilities;
|
|
26
|
+
} catch {
|
|
27
|
+
/* keep defaults */
|
|
28
|
+
}
|
|
29
|
+
return { user: locals.user, impersonating: !!locals.session?.impersonatedBy, capabilities };
|
|
30
|
+
};
|