@baasix/baasix 0.1.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/LICENSE.MD +85 -0
- package/README.md +526 -0
- package/assets/banner.jpg +0 -0
- package/assets/banner_small.jpg +0 -0
- package/assets/logo_icon.svg +20 -0
- package/assets/logo_icon_rounded.svg +20 -0
- package/dist/LICENSE.MD +85 -0
- package/dist/README.md +526 -0
- package/dist/app/404/index.html +1 -0
- package/dist/app/404.html +1 -0
- package/dist/app/_next/static/chunks/041e1f03-56ae8a902a7f2fe6.js +24 -0
- package/dist/app/_next/static/chunks/1117-05479929a8da73e3.js +1 -0
- package/dist/app/_next/static/chunks/1299.77cc7b7b76b75cba.js +1 -0
- package/dist/app/_next/static/chunks/1303-35a96e9c9cdeab9d.js +1 -0
- package/dist/app/_next/static/chunks/1509-56ac00cdaaecdf53.js +1 -0
- package/dist/app/_next/static/chunks/1668-e3eabd0f6753c780.js +1 -0
- package/dist/app/_next/static/chunks/1783-d9fb550fd324300c.js +1 -0
- package/dist/app/_next/static/chunks/2117-29b5fa47421595ad.js +2 -0
- package/dist/app/_next/static/chunks/2344.35b46d2179a765b5.js +1 -0
- package/dist/app/_next/static/chunks/257.990da16794a31292.js +1 -0
- package/dist/app/_next/static/chunks/2676-73b0ee7c80073a84.js +1 -0
- package/dist/app/_next/static/chunks/3563-b8842744384391fe.js +1 -0
- package/dist/app/_next/static/chunks/363642f4-933b579ed3c85f60.js +1 -0
- package/dist/app/_next/static/chunks/3817-e20c8f0a0810fc95.js +1 -0
- package/dist/app/_next/static/chunks/3834.84944e390d902509.js +2 -0
- package/dist/app/_next/static/chunks/4043-3a30c8a75896f241.js +1 -0
- package/dist/app/_next/static/chunks/4225-14090c7c0cd9dec6.js +1 -0
- package/dist/app/_next/static/chunks/4438-c9a12ca15b6e9160.js +1 -0
- package/dist/app/_next/static/chunks/4458-679fd0c6884f456a.js +1 -0
- package/dist/app/_next/static/chunks/4475-8bdfbd536fba8c48.js +1 -0
- package/dist/app/_next/static/chunks/4883-8a924721bb21b3b0.js +1 -0
- package/dist/app/_next/static/chunks/489-683ab07188f9df2b.js +1 -0
- package/dist/app/_next/static/chunks/4952-1b97320cf61f3f21.js +1 -0
- package/dist/app/_next/static/chunks/5094-8d53e403235d4ca6.js +1 -0
- package/dist/app/_next/static/chunks/5101-3a146e0625747ad1.js +1 -0
- package/dist/app/_next/static/chunks/54a60aa6-d9747982e0a81f58.js +79 -0
- package/dist/app/_next/static/chunks/5650-f096291df402bfc2.js +1 -0
- package/dist/app/_next/static/chunks/600-539045311240f579.js +1 -0
- package/dist/app/_next/static/chunks/6170-803b82e19d3ade6d.js +89 -0
- package/dist/app/_next/static/chunks/6241-30d7169d1010e5a4.js +1 -0
- package/dist/app/_next/static/chunks/6530-a91e10cffa4200c4.js +1 -0
- package/dist/app/_next/static/chunks/6547-4bbbdb5c399aef1e.js +1 -0
- package/dist/app/_next/static/chunks/6712-781937c53a2c49da.js +1 -0
- package/dist/app/_next/static/chunks/6fcbdc68-90be1a5480b8d353.js +1 -0
- package/dist/app/_next/static/chunks/70e0d97a-aeaf0cdc26ba1a58.js +1 -0
- package/dist/app/_next/static/chunks/7214-5154a89d08d24dde.js +1 -0
- package/dist/app/_next/static/chunks/7324-b53229c59a640880.js +10 -0
- package/dist/app/_next/static/chunks/7636-66424f0b51d350e9.js +1 -0
- package/dist/app/_next/static/chunks/7874-39a3f2541165a675.js +1 -0
- package/dist/app/_next/static/chunks/7982-9da12b83f11e3f5f.js +1 -0
- package/dist/app/_next/static/chunks/8213a2eb-da25a3b3c5521b2b.js +1 -0
- package/dist/app/_next/static/chunks/8473-6598318371eca31b.js +1 -0
- package/dist/app/_next/static/chunks/8640fa6b-72e43370f68e5587.js +1 -0
- package/dist/app/_next/static/chunks/9090-3ef676f29c95f1c7.js +1 -0
- package/dist/app/_next/static/chunks/9124-a02f9e209e6e3cce.js +1 -0
- package/dist/app/_next/static/chunks/926-156f32067d111d6b.js +1 -0
- package/dist/app/_next/static/chunks/9487-b17481605e513b83.js +1 -0
- package/dist/app/_next/static/chunks/9599-a7e572bb88c3392b.js +1 -0
- package/dist/app/_next/static/chunks/9881-419697138376e755.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/all-activity/page-8917930b4d663405.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/email-log/page-b27a6ee32782d7df.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/notifications/page-b7eda523ede2702c.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/page-1cfa62d1caedaed0.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/sessions/page-3e21e20db90aeff7.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-executions/page-27bcc26b747fb29b.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-logs/page-9f9e9e952aef436e.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/change-password/page-8d61aa499eabb127.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/dashboard/page-1ceeac9e72997a8a.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/data-browser/page-8cda2b57759dd670.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/file-manager/page-8c6f1b1da66ad7e4.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/layout-f70d225b2759c998.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/migrations/page-aacec8f7cfb40ab2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/permissions/page-828110cfcde429c6.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/project/page-420e794bb76bd204.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/roles/page-9001d02b28f70708.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/schema/page-899574f35091dd58.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/tasks/page-ad7ab3e27c83f44f.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/edit/page-bd83414cb8c4cb04.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/page-3181447f8772b1d3.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/tenants/page-ef9bfbacef5a1d73.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/invites/page-480306b7b2bbac7e.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/list/page-74da51254c2606b3.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/page-e99c6f0b915001b2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/preferences/page-1a935630ce8f2b12.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/user-roles/page-901dfb8ea1f39ca8.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/detail/page-9a6b839aea688ca4.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/edit/page-11774efbc2fecae2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/execution/page-8ec1aea90412c03d.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/page-88bc5b36ccb0a1f7.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/forgot-password/page-ed263fd46ef81c20.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/layout-f538977545844af8.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/login/page-c0a10b137f346096.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/register/page-4cb7644893efd9b3.js +1 -0
- package/dist/app/_next/static/chunks/app/_not-found/page-653f8815b78256cc.js +1 -0
- package/dist/app/_next/static/chunks/app/layout-591ca7a3e16528a1.js +1 -0
- package/dist/app/_next/static/chunks/app/page-dd19d124b5fa2577.js +1 -0
- package/dist/app/_next/static/chunks/c37d3baf.c2ff165f5b02c692.js +1 -0
- package/dist/app/_next/static/chunks/d0deef33.0379166a4ec23470.js +1 -0
- package/dist/app/_next/static/chunks/fd9d1056-54169f07cd680d6c.js +1 -0
- package/dist/app/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
- package/dist/app/_next/static/chunks/main-324e91f5a430cddf.js +1 -0
- package/dist/app/_next/static/chunks/main-app-55bcae20c77aaf0e.js +1 -0
- package/dist/app/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
- package/dist/app/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
- package/dist/app/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/app/_next/static/chunks/webpack-2c306566f7ee1b63.js +1 -0
- package/dist/app/_next/static/css/6c4002bae4e236b2.css +3 -0
- package/dist/app/_next/static/css/a275cc2b185e04f8.css +1 -0
- package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_buildManifest.js +1 -0
- package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_ssgManifest.js +1 -0
- package/dist/app/activity-log/all-activity/index.html +1 -0
- package/dist/app/activity-log/all-activity/index.txt +14 -0
- package/dist/app/activity-log/email-log/index.html +1 -0
- package/dist/app/activity-log/email-log/index.txt +14 -0
- package/dist/app/activity-log/index.html +1 -0
- package/dist/app/activity-log/index.txt +14 -0
- package/dist/app/activity-log/notifications/index.html +1 -0
- package/dist/app/activity-log/notifications/index.txt +14 -0
- package/dist/app/activity-log/sessions/index.html +1 -0
- package/dist/app/activity-log/sessions/index.txt +14 -0
- package/dist/app/activity-log/workflow-executions/index.html +1 -0
- package/dist/app/activity-log/workflow-executions/index.txt +14 -0
- package/dist/app/activity-log/workflow-logs/index.html +1 -0
- package/dist/app/activity-log/workflow-logs/index.txt +14 -0
- package/dist/app/change-password/index.html +1 -0
- package/dist/app/change-password/index.txt +14 -0
- package/dist/app/dashboard/index.html +1 -0
- package/dist/app/dashboard/index.txt +14 -0
- package/dist/app/data-browser/index.html +1 -0
- package/dist/app/data-browser/index.txt +14 -0
- package/dist/app/file-manager/index.html +1 -0
- package/dist/app/file-manager/index.txt +14 -0
- package/dist/app/forgot-password/index.html +1 -0
- package/dist/app/forgot-password/index.txt +13 -0
- package/dist/app/index.html +1 -0
- package/dist/app/index.txt +9 -0
- package/dist/app/login/index.html +1 -0
- package/dist/app/login/index.txt +13 -0
- package/dist/app/logo-dark.png +0 -0
- package/dist/app/logo-icon.svg +81 -0
- package/dist/app/logo-light.png +0 -0
- package/dist/app/register/index.html +1 -0
- package/dist/app/register/index.txt +13 -0
- package/dist/app/settings/migrations/index.html +1 -0
- package/dist/app/settings/migrations/index.txt +14 -0
- package/dist/app/settings/permissions/index.html +1 -0
- package/dist/app/settings/permissions/index.txt +14 -0
- package/dist/app/settings/project/index.html +1 -0
- package/dist/app/settings/project/index.txt +14 -0
- package/dist/app/settings/roles/index.html +1 -0
- package/dist/app/settings/roles/index.txt +14 -0
- package/dist/app/settings/schema/index.html +1 -0
- package/dist/app/settings/schema/index.txt +14 -0
- package/dist/app/settings/tasks/index.html +1 -0
- package/dist/app/settings/tasks/index.txt +14 -0
- package/dist/app/settings/templates/edit/index.html +1 -0
- package/dist/app/settings/templates/edit/index.txt +14 -0
- package/dist/app/settings/templates/index.html +1 -0
- package/dist/app/settings/templates/index.txt +14 -0
- package/dist/app/settings/tenants/index.html +1 -0
- package/dist/app/settings/tenants/index.txt +14 -0
- package/dist/app/users/index.html +1 -0
- package/dist/app/users/index.txt +14 -0
- package/dist/app/users/invites/index.html +1 -0
- package/dist/app/users/invites/index.txt +14 -0
- package/dist/app/users/list/index.html +1 -0
- package/dist/app/users/list/index.txt +14 -0
- package/dist/app/users/preferences/index.html +1 -0
- package/dist/app/users/preferences/index.txt +14 -0
- package/dist/app/users/user-roles/index.html +1 -0
- package/dist/app/users/user-roles/index.txt +14 -0
- package/dist/app/workflows/detail/index.html +1 -0
- package/dist/app/workflows/detail/index.txt +14 -0
- package/dist/app/workflows/edit/index.html +1 -0
- package/dist/app/workflows/edit/index.txt +14 -0
- package/dist/app/workflows/execution/index.html +1 -0
- package/dist/app/workflows/execution/index.txt +14 -0
- package/dist/app/workflows/index.html +1 -0
- package/dist/app/workflows/index.txt +14 -0
- package/dist/app.d.ts +36 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +546 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/adapters/baasix-adapter.d.ts +12 -0
- package/dist/auth/adapters/baasix-adapter.d.ts.map +1 -0
- package/dist/auth/adapters/baasix-adapter.js +318 -0
- package/dist/auth/adapters/baasix-adapter.js.map +1 -0
- package/dist/auth/adapters/index.d.ts +6 -0
- package/dist/auth/adapters/index.d.ts.map +1 -0
- package/dist/auth/adapters/index.js +5 -0
- package/dist/auth/adapters/index.js.map +1 -0
- package/dist/auth/core.d.ts +73 -0
- package/dist/auth/core.d.ts.map +1 -0
- package/dist/auth/core.js +528 -0
- package/dist/auth/core.js.map +1 -0
- package/dist/auth/index.d.ts +56 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +58 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth2/index.d.ts +5 -0
- package/dist/auth/oauth2/index.d.ts.map +1 -0
- package/dist/auth/oauth2/index.js +5 -0
- package/dist/auth/oauth2/index.js.map +1 -0
- package/dist/auth/oauth2/utils.d.ts +90 -0
- package/dist/auth/oauth2/utils.d.ts.map +1 -0
- package/dist/auth/oauth2/utils.js +167 -0
- package/dist/auth/oauth2/utils.js.map +1 -0
- package/dist/auth/providers/apple.d.ts +28 -0
- package/dist/auth/providers/apple.d.ts.map +1 -0
- package/dist/auth/providers/apple.js +192 -0
- package/dist/auth/providers/apple.js.map +1 -0
- package/dist/auth/providers/credential.d.ts +87 -0
- package/dist/auth/providers/credential.d.ts.map +1 -0
- package/dist/auth/providers/credential.js +162 -0
- package/dist/auth/providers/credential.js.map +1 -0
- package/dist/auth/providers/facebook.d.ts +26 -0
- package/dist/auth/providers/facebook.d.ts.map +1 -0
- package/dist/auth/providers/facebook.js +112 -0
- package/dist/auth/providers/facebook.js.map +1 -0
- package/dist/auth/providers/github.d.ts +29 -0
- package/dist/auth/providers/github.d.ts.map +1 -0
- package/dist/auth/providers/github.js +144 -0
- package/dist/auth/providers/github.js.map +1 -0
- package/dist/auth/providers/google.d.ts +32 -0
- package/dist/auth/providers/google.d.ts.map +1 -0
- package/dist/auth/providers/google.js +145 -0
- package/dist/auth/providers/google.js.map +1 -0
- package/dist/auth/providers/index.d.ts +22 -0
- package/dist/auth/providers/index.d.ts.map +1 -0
- package/dist/auth/providers/index.js +17 -0
- package/dist/auth/providers/index.js.map +1 -0
- package/dist/auth/routes.d.ts +63 -0
- package/dist/auth/routes.d.ts.map +1 -0
- package/dist/auth/routes.js +827 -0
- package/dist/auth/routes.js.map +1 -0
- package/dist/auth/services/index.d.ts +10 -0
- package/dist/auth/services/index.d.ts.map +1 -0
- package/dist/auth/services/index.js +7 -0
- package/dist/auth/services/index.js.map +1 -0
- package/dist/auth/services/session.d.ts +81 -0
- package/dist/auth/services/session.d.ts.map +1 -0
- package/dist/auth/services/session.js +186 -0
- package/dist/auth/services/session.js.map +1 -0
- package/dist/auth/services/token.d.ts +41 -0
- package/dist/auth/services/token.d.ts.map +1 -0
- package/dist/auth/services/token.js +44 -0
- package/dist/auth/services/token.js.map +1 -0
- package/dist/auth/services/verification.d.ts +77 -0
- package/dist/auth/services/verification.d.ts.map +1 -0
- package/dist/auth/services/verification.js +143 -0
- package/dist/auth/services/verification.js.map +1 -0
- package/dist/auth/types.d.ts +318 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +6 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/customTypes/arrays.d.ts +200 -0
- package/dist/customTypes/arrays.d.ts.map +1 -0
- package/dist/customTypes/arrays.js +309 -0
- package/dist/customTypes/arrays.js.map +1 -0
- package/dist/customTypes/index.d.ts +8 -0
- package/dist/customTypes/index.d.ts.map +1 -0
- package/dist/customTypes/index.js +11 -0
- package/dist/customTypes/index.js.map +1 -0
- package/dist/customTypes/postgis.d.ts +146 -0
- package/dist/customTypes/postgis.d.ts.map +1 -0
- package/dist/customTypes/postgis.js +315 -0
- package/dist/customTypes/postgis.js.map +1 -0
- package/dist/customTypes/ranges.d.ts +128 -0
- package/dist/customTypes/ranges.d.ts.map +1 -0
- package/dist/customTypes/ranges.js +257 -0
- package/dist/customTypes/ranges.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts +29 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts.map +1 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.js +72 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.js.map +1 -0
- package/dist/migrations/_example_migration.d.ts +31 -0
- package/dist/migrations/_example_migration.d.ts.map +1 -0
- package/dist/migrations/_example_migration.js +75 -0
- package/dist/migrations/_example_migration.js.map +1 -0
- package/dist/plugins/definePlugin.d.ts +49 -0
- package/dist/plugins/definePlugin.d.ts.map +1 -0
- package/dist/plugins/definePlugin.js +131 -0
- package/dist/plugins/definePlugin.js.map +1 -0
- package/dist/plugins/softDelete.d.ts +179 -0
- package/dist/plugins/softDelete.d.ts.map +1 -0
- package/dist/plugins/softDelete.js +235 -0
- package/dist/plugins/softDelete.js.map +1 -0
- package/dist/routes/auth.route.d.ts +14 -0
- package/dist/routes/auth.route.d.ts.map +1 -0
- package/dist/routes/auth.route.js +421 -0
- package/dist/routes/auth.route.js.map +1 -0
- package/dist/routes/file.route.d.ts +7 -0
- package/dist/routes/file.route.d.ts.map +1 -0
- package/dist/routes/file.route.js +274 -0
- package/dist/routes/file.route.js.map +1 -0
- package/dist/routes/items.route.d.ts +7 -0
- package/dist/routes/items.route.d.ts.map +1 -0
- package/dist/routes/items.route.js +369 -0
- package/dist/routes/items.route.js.map +1 -0
- package/dist/routes/migration.route.d.ts +7 -0
- package/dist/routes/migration.route.d.ts.map +1 -0
- package/dist/routes/migration.route.js +225 -0
- package/dist/routes/migration.route.js.map +1 -0
- package/dist/routes/notification.route.d.ts +7 -0
- package/dist/routes/notification.route.d.ts.map +1 -0
- package/dist/routes/notification.route.js +124 -0
- package/dist/routes/notification.route.js.map +1 -0
- package/dist/routes/openapi.route.d.ts +7 -0
- package/dist/routes/openapi.route.d.ts.map +1 -0
- package/dist/routes/openapi.route.js +2169 -0
- package/dist/routes/openapi.route.js.map +1 -0
- package/dist/routes/permission.route.d.ts +7 -0
- package/dist/routes/permission.route.d.ts.map +1 -0
- package/dist/routes/permission.route.js +158 -0
- package/dist/routes/permission.route.js.map +1 -0
- package/dist/routes/realtime.route.d.ts +21 -0
- package/dist/routes/realtime.route.d.ts.map +1 -0
- package/dist/routes/realtime.route.js +243 -0
- package/dist/routes/realtime.route.js.map +1 -0
- package/dist/routes/reports.route.d.ts +7 -0
- package/dist/routes/reports.route.d.ts.map +1 -0
- package/dist/routes/reports.route.js +95 -0
- package/dist/routes/reports.route.js.map +1 -0
- package/dist/routes/schema.route.d.ts +7 -0
- package/dist/routes/schema.route.d.ts.map +1 -0
- package/dist/routes/schema.route.js +1780 -0
- package/dist/routes/schema.route.js.map +1 -0
- package/dist/routes/settings.route.d.ts +7 -0
- package/dist/routes/settings.route.d.ts.map +1 -0
- package/dist/routes/settings.route.js +154 -0
- package/dist/routes/settings.route.js.map +1 -0
- package/dist/routes/templates.route.d.ts +7 -0
- package/dist/routes/templates.route.d.ts.map +1 -0
- package/dist/routes/templates.route.js +91 -0
- package/dist/routes/templates.route.js.map +1 -0
- package/dist/routes/utils.route.d.ts +7 -0
- package/dist/routes/utils.route.d.ts.map +1 -0
- package/dist/routes/utils.route.js +33 -0
- package/dist/routes/utils.route.js.map +1 -0
- package/dist/routes/workflow.route.d.ts +7 -0
- package/dist/routes/workflow.route.d.ts.map +1 -0
- package/dist/routes/workflow.route.js +787 -0
- package/dist/routes/workflow.route.js.map +1 -0
- package/dist/services/AssetsService.d.ts +39 -0
- package/dist/services/AssetsService.d.ts.map +1 -0
- package/dist/services/AssetsService.js +255 -0
- package/dist/services/AssetsService.js.map +1 -0
- package/dist/services/CacheService.d.ts +169 -0
- package/dist/services/CacheService.d.ts.map +1 -0
- package/dist/services/CacheService.js +722 -0
- package/dist/services/CacheService.js.map +1 -0
- package/dist/services/FilesService.d.ts +30 -0
- package/dist/services/FilesService.d.ts.map +1 -0
- package/dist/services/FilesService.js +268 -0
- package/dist/services/FilesService.js.map +1 -0
- package/dist/services/HooksManager.d.ts +38 -0
- package/dist/services/HooksManager.d.ts.map +1 -0
- package/dist/services/HooksManager.js +165 -0
- package/dist/services/HooksManager.js.map +1 -0
- package/dist/services/ItemsService.d.ts +273 -0
- package/dist/services/ItemsService.d.ts.map +1 -0
- package/dist/services/ItemsService.js +2458 -0
- package/dist/services/ItemsService.js.map +1 -0
- package/dist/services/MailService.d.ts +76 -0
- package/dist/services/MailService.d.ts.map +1 -0
- package/dist/services/MailService.js +585 -0
- package/dist/services/MailService.js.map +1 -0
- package/dist/services/MigrationService.d.ts +243 -0
- package/dist/services/MigrationService.d.ts.map +1 -0
- package/dist/services/MigrationService.js +914 -0
- package/dist/services/MigrationService.js.map +1 -0
- package/dist/services/NotificationService.d.ts +35 -0
- package/dist/services/NotificationService.d.ts.map +1 -0
- package/dist/services/NotificationService.js +159 -0
- package/dist/services/NotificationService.js.map +1 -0
- package/dist/services/PermissionService.d.ts +128 -0
- package/dist/services/PermissionService.d.ts.map +1 -0
- package/dist/services/PermissionService.js +373 -0
- package/dist/services/PermissionService.js.map +1 -0
- package/dist/services/PluginManager.d.ts +138 -0
- package/dist/services/PluginManager.d.ts.map +1 -0
- package/dist/services/PluginManager.js +463 -0
- package/dist/services/PluginManager.js.map +1 -0
- package/dist/services/RealtimeService.d.ts +209 -0
- package/dist/services/RealtimeService.d.ts.map +1 -0
- package/dist/services/RealtimeService.js +978 -0
- package/dist/services/RealtimeService.js.map +1 -0
- package/dist/services/ReportService.d.ts +13 -0
- package/dist/services/ReportService.d.ts.map +1 -0
- package/dist/services/ReportService.js +91 -0
- package/dist/services/ReportService.js.map +1 -0
- package/dist/services/SettingsService.d.ts +60 -0
- package/dist/services/SettingsService.d.ts.map +1 -0
- package/dist/services/SettingsService.js +474 -0
- package/dist/services/SettingsService.js.map +1 -0
- package/dist/services/SocketService.d.ts +129 -0
- package/dist/services/SocketService.d.ts.map +1 -0
- package/dist/services/SocketService.js +600 -0
- package/dist/services/SocketService.js.map +1 -0
- package/dist/services/StatsService.d.ts +10 -0
- package/dist/services/StatsService.d.ts.map +1 -0
- package/dist/services/StatsService.js +40 -0
- package/dist/services/StatsService.js.map +1 -0
- package/dist/services/StorageService.d.ts +20 -0
- package/dist/services/StorageService.d.ts.map +1 -0
- package/dist/services/StorageService.js +164 -0
- package/dist/services/StorageService.js.map +1 -0
- package/dist/services/TasksService.d.ts +74 -0
- package/dist/services/TasksService.d.ts.map +1 -0
- package/dist/services/TasksService.js +404 -0
- package/dist/services/TasksService.js.map +1 -0
- package/dist/services/WorkflowService.d.ts +305 -0
- package/dist/services/WorkflowService.d.ts.map +1 -0
- package/dist/services/WorkflowService.js +1811 -0
- package/dist/services/WorkflowService.js.map +1 -0
- package/dist/templates/logo/logo.png +0 -0
- package/dist/templates/mails/default.liquid +23 -0
- package/dist/types/aggregation.d.ts +40 -0
- package/dist/types/aggregation.d.ts.map +1 -0
- package/dist/types/aggregation.js +6 -0
- package/dist/types/aggregation.js.map +1 -0
- package/dist/types/assets.d.ts +32 -0
- package/dist/types/assets.d.ts.map +1 -0
- package/dist/types/assets.js +6 -0
- package/dist/types/assets.js.map +1 -0
- package/dist/types/auth.d.ts +50 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +6 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/cache.d.ts +47 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +6 -0
- package/dist/types/cache.js.map +1 -0
- package/dist/types/database.d.ts +16 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/database.js +6 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/fields.d.ts +71 -0
- package/dist/types/fields.d.ts.map +1 -0
- package/dist/types/fields.js +6 -0
- package/dist/types/fields.js.map +1 -0
- package/dist/types/files.d.ts +33 -0
- package/dist/types/files.d.ts.map +1 -0
- package/dist/types/files.js +6 -0
- package/dist/types/files.js.map +1 -0
- package/dist/types/hooks.d.ts +29 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +6 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/import-export.d.ts +62 -0
- package/dist/types/import-export.d.ts.map +1 -0
- package/dist/types/import-export.js +6 -0
- package/dist/types/import-export.js.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +58 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mail.d.ts +34 -0
- package/dist/types/mail.d.ts.map +1 -0
- package/dist/types/mail.js +6 -0
- package/dist/types/mail.js.map +1 -0
- package/dist/types/notifications.d.ts +16 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/types/notifications.js +6 -0
- package/dist/types/notifications.js.map +1 -0
- package/dist/types/plugin.d.ts +351 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +8 -0
- package/dist/types/plugin.js.map +1 -0
- package/dist/types/query.d.ts +71 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/query.js +6 -0
- package/dist/types/query.js.map +1 -0
- package/dist/types/relations.d.ts +111 -0
- package/dist/types/relations.d.ts.map +1 -0
- package/dist/types/relations.js +6 -0
- package/dist/types/relations.js.map +1 -0
- package/dist/types/reports.d.ts +17 -0
- package/dist/types/reports.d.ts.map +1 -0
- package/dist/types/reports.js +6 -0
- package/dist/types/reports.js.map +1 -0
- package/dist/types/schema.d.ts +26 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +6 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/seed.d.ts +27 -0
- package/dist/types/seed.d.ts.map +1 -0
- package/dist/types/seed.js +6 -0
- package/dist/types/seed.js.map +1 -0
- package/dist/types/services.d.ts +68 -0
- package/dist/types/services.d.ts.map +1 -0
- package/dist/types/services.js +6 -0
- package/dist/types/services.js.map +1 -0
- package/dist/types/settings.d.ts +36 -0
- package/dist/types/settings.d.ts.map +1 -0
- package/dist/types/settings.js +6 -0
- package/dist/types/settings.js.map +1 -0
- package/dist/types/sockets.d.ts +26 -0
- package/dist/types/sockets.d.ts.map +1 -0
- package/dist/types/sockets.js +6 -0
- package/dist/types/sockets.js.map +1 -0
- package/dist/types/sort.d.ts +25 -0
- package/dist/types/sort.d.ts.map +1 -0
- package/dist/types/sort.js +6 -0
- package/dist/types/sort.js.map +1 -0
- package/dist/types/spatial.d.ts +19 -0
- package/dist/types/spatial.d.ts.map +1 -0
- package/dist/types/spatial.js +6 -0
- package/dist/types/spatial.js.map +1 -0
- package/dist/types/stats.d.ts +21 -0
- package/dist/types/stats.d.ts.map +1 -0
- package/dist/types/stats.js +6 -0
- package/dist/types/stats.js.map +1 -0
- package/dist/types/storage.d.ts +19 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +6 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/types/tasks.d.ts +14 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +6 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/types/utils.d.ts +54 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +6 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types/workflow.d.ts +17 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +6 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/aggregationUtils.d.ts +192 -0
- package/dist/utils/aggregationUtils.d.ts.map +1 -0
- package/dist/utils/aggregationUtils.js +450 -0
- package/dist/utils/aggregationUtils.js.map +1 -0
- package/dist/utils/auth.d.ts +93 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +557 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/cache.d.ts +64 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +464 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/common.d.ts +53 -0
- package/dist/utils/common.d.ts.map +1 -0
- package/dist/utils/common.js +162 -0
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/db.d.ts +101 -0
- package/dist/utils/db.d.ts.map +1 -0
- package/dist/utils/db.js +413 -0
- package/dist/utils/db.js.map +1 -0
- package/dist/utils/dirname.d.ts +30 -0
- package/dist/utils/dirname.d.ts.map +1 -0
- package/dist/utils/dirname.js +95 -0
- package/dist/utils/dirname.js.map +1 -0
- package/dist/utils/dynamicVariableResolver.d.ts +17 -0
- package/dist/utils/dynamicVariableResolver.d.ts.map +1 -0
- package/dist/utils/dynamicVariableResolver.js +262 -0
- package/dist/utils/dynamicVariableResolver.js.map +1 -0
- package/dist/utils/env.d.ts +38 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +80 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errorHandler.d.ts +14 -0
- package/dist/utils/errorHandler.d.ts.map +1 -0
- package/dist/utils/errorHandler.js +79 -0
- package/dist/utils/errorHandler.js.map +1 -0
- package/dist/utils/fieldExpansion.d.ts +30 -0
- package/dist/utils/fieldExpansion.d.ts.map +1 -0
- package/dist/utils/fieldExpansion.js +145 -0
- package/dist/utils/fieldExpansion.js.map +1 -0
- package/dist/utils/fieldUtils.d.ts +179 -0
- package/dist/utils/fieldUtils.d.ts.map +1 -0
- package/dist/utils/fieldUtils.js +424 -0
- package/dist/utils/fieldUtils.js.map +1 -0
- package/dist/utils/filterOperators.d.ts +472 -0
- package/dist/utils/filterOperators.d.ts.map +1 -0
- package/dist/utils/filterOperators.js +1229 -0
- package/dist/utils/filterOperators.js.map +1 -0
- package/dist/utils/importUtils.d.ts +127 -0
- package/dist/utils/importUtils.d.ts.map +1 -0
- package/dist/utils/importUtils.js +437 -0
- package/dist/utils/importUtils.js.map +1 -0
- package/dist/utils/index.d.ts +75 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +101 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +41 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +217 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/orderUtils.d.ts +117 -0
- package/dist/utils/orderUtils.d.ts.map +1 -0
- package/dist/utils/orderUtils.js +249 -0
- package/dist/utils/orderUtils.js.map +1 -0
- package/dist/utils/queryBuilder.d.ts +118 -0
- package/dist/utils/queryBuilder.d.ts.map +1 -0
- package/dist/utils/queryBuilder.js +489 -0
- package/dist/utils/queryBuilder.js.map +1 -0
- package/dist/utils/relationLoader.d.ts +65 -0
- package/dist/utils/relationLoader.d.ts.map +1 -0
- package/dist/utils/relationLoader.js +1081 -0
- package/dist/utils/relationLoader.js.map +1 -0
- package/dist/utils/relationPathResolver.d.ts +30 -0
- package/dist/utils/relationPathResolver.d.ts.map +1 -0
- package/dist/utils/relationPathResolver.js +173 -0
- package/dist/utils/relationPathResolver.js.map +1 -0
- package/dist/utils/relationUtils.d.ts +139 -0
- package/dist/utils/relationUtils.d.ts.map +1 -0
- package/dist/utils/relationUtils.js +711 -0
- package/dist/utils/relationUtils.js.map +1 -0
- package/dist/utils/router.d.ts +6 -0
- package/dist/utils/router.d.ts.map +1 -0
- package/dist/utils/router.js +95 -0
- package/dist/utils/router.js.map +1 -0
- package/dist/utils/schema.d.ts +88 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +24 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/schemaManager.d.ts +238 -0
- package/dist/utils/schemaManager.d.ts.map +1 -0
- package/dist/utils/schemaManager.js +1992 -0
- package/dist/utils/schemaManager.js.map +1 -0
- package/dist/utils/schemaValidator.d.ts +83 -0
- package/dist/utils/schemaValidator.d.ts.map +1 -0
- package/dist/utils/schemaValidator.js +491 -0
- package/dist/utils/schemaValidator.js.map +1 -0
- package/dist/utils/seed.d.ts +45 -0
- package/dist/utils/seed.d.ts.map +1 -0
- package/dist/utils/seed.js +248 -0
- package/dist/utils/seed.js.map +1 -0
- package/dist/utils/sessionCleanup.d.ts +10 -0
- package/dist/utils/sessionCleanup.d.ts.map +1 -0
- package/dist/utils/sessionCleanup.js +49 -0
- package/dist/utils/sessionCleanup.js.map +1 -0
- package/dist/utils/sortUtils.d.ts +117 -0
- package/dist/utils/sortUtils.d.ts.map +1 -0
- package/dist/utils/sortUtils.js +232 -0
- package/dist/utils/sortUtils.js.map +1 -0
- package/dist/utils/spatialUtils.d.ts +244 -0
- package/dist/utils/spatialUtils.d.ts.map +1 -0
- package/dist/utils/spatialUtils.js +359 -0
- package/dist/utils/spatialUtils.js.map +1 -0
- package/dist/utils/systemschema.d.ts +11040 -0
- package/dist/utils/systemschema.d.ts.map +1 -0
- package/dist/utils/systemschema.js +1777 -0
- package/dist/utils/systemschema.js.map +1 -0
- package/dist/utils/tenantUtils.d.ts +34 -0
- package/dist/utils/tenantUtils.d.ts.map +1 -0
- package/dist/utils/tenantUtils.js +124 -0
- package/dist/utils/tenantUtils.js.map +1 -0
- package/dist/utils/typeMapper.d.ts +25 -0
- package/dist/utils/typeMapper.d.ts.map +1 -0
- package/dist/utils/typeMapper.js +282 -0
- package/dist/utils/typeMapper.js.map +1 -0
- package/dist/utils/valueValidator.d.ts +60 -0
- package/dist/utils/valueValidator.d.ts.map +1 -0
- package/dist/utils/valueValidator.js +303 -0
- package/dist/utils/valueValidator.js.map +1 -0
- package/dist/utils/workflow.d.ts +87 -0
- package/dist/utils/workflow.d.ts.map +1 -0
- package/dist/utils/workflow.js +205 -0
- package/dist/utils/workflow.js.map +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,827 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Route Handler
|
|
3
|
+
* Express routes for the auth module
|
|
4
|
+
*/
|
|
5
|
+
import { createAuth } from "./core.js";
|
|
6
|
+
import { getCache } from "../utils/cache.js";
|
|
7
|
+
import { isAdmin, getPublicRole } from "../utils/auth.js";
|
|
8
|
+
// Store OAuth state in cache for validation
|
|
9
|
+
const OAUTH_STATE_PREFIX = "oauth_state:";
|
|
10
|
+
const OAUTH_STATE_TTL = 600; // 10 minutes
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to set token in response based on auth mode
|
|
13
|
+
*/
|
|
14
|
+
export const setTokenInResponse = (res, token, authMode, env) => {
|
|
15
|
+
if (authMode === "cookie") {
|
|
16
|
+
// Get cookie settings from environment variables with secure defaults
|
|
17
|
+
const secureEnv = env?.get("AUTH_COOKIE_SECURE");
|
|
18
|
+
const cookieOptions = {
|
|
19
|
+
httpOnly: env?.get("AUTH_COOKIE_HTTP_ONLY") !== "false", // Default: true (secure)
|
|
20
|
+
secure: secureEnv !== undefined ? secureEnv === "true" : env?.get("NODE_ENV") === "production", // Explicit value or default to true in production
|
|
21
|
+
sameSite: env?.get("AUTH_COOKIE_SAME_SITE") || (env?.get("NODE_ENV") === "production" ? "strict" : "lax"), // Default: strict in prod, lax in dev
|
|
22
|
+
maxAge: (parseInt(env?.get("ACCESS_TOKEN_EXPIRES_IN") || "604800") || 604800) * 1000, // Default 7 days
|
|
23
|
+
path: env?.get("AUTH_COOKIE_PATH") || "/", // Default: all paths
|
|
24
|
+
};
|
|
25
|
+
// Add domain if specified in environment
|
|
26
|
+
if (env?.get("AUTH_COOKIE_DOMAIN")) {
|
|
27
|
+
cookieOptions.domain = env.get("AUTH_COOKIE_DOMAIN");
|
|
28
|
+
}
|
|
29
|
+
res.cookie("token", token, cookieOptions);
|
|
30
|
+
return { token, message: "Authentication successful", authMode: "cookie" };
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// For 'jwt' mode or if not specified, send token in response body
|
|
34
|
+
return { token, authMode: "jwt" };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// Note: Express Request is augmented in utils/auth.v2.ts
|
|
38
|
+
// The 'auth' and 'accountability' properties are added there
|
|
39
|
+
/**
|
|
40
|
+
* Create auth routes for Express
|
|
41
|
+
*/
|
|
42
|
+
export function createAuthRoutes(app, options) {
|
|
43
|
+
const basePath = options.basePath || "/auth";
|
|
44
|
+
const auth = createAuth(options);
|
|
45
|
+
const cache = getCache();
|
|
46
|
+
// Helper to get allowed app URLs
|
|
47
|
+
async function getAllowedAppUrls() {
|
|
48
|
+
try {
|
|
49
|
+
const staticUrls = options.env?.get("AUTH_APP_URL")?.split(",").map((url) => url.trim()) || [];
|
|
50
|
+
const dynamicUrls = options.settingsService
|
|
51
|
+
? await options.settingsService.getAllSettingsUrls()
|
|
52
|
+
: [];
|
|
53
|
+
return [...new Set([...staticUrls, ...dynamicUrls])];
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error("Error getting allowed app URLs:", error);
|
|
57
|
+
return options.env?.get("AUTH_APP_URL")?.split(",").map((url) => url.trim()) || [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Helper to validate URL
|
|
61
|
+
async function isValidAppUrl(url) {
|
|
62
|
+
if (!url)
|
|
63
|
+
return false;
|
|
64
|
+
const allowedUrls = await getAllowedAppUrls();
|
|
65
|
+
return allowedUrls.includes(url);
|
|
66
|
+
}
|
|
67
|
+
// Helper to store OAuth state
|
|
68
|
+
async function storeOAuthState(state, data) {
|
|
69
|
+
await cache.set(`${OAUTH_STATE_PREFIX}${state}`, data, OAUTH_STATE_TTL);
|
|
70
|
+
}
|
|
71
|
+
// Helper to get and delete OAuth state
|
|
72
|
+
async function getOAuthState(state) {
|
|
73
|
+
const data = await cache.get(`${OAUTH_STATE_PREFIX}${state}`);
|
|
74
|
+
if (data) {
|
|
75
|
+
await cache.delete(`${OAUTH_STATE_PREFIX}${state}`);
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
// ==================== Registration ====================
|
|
80
|
+
app.post(`${basePath}/register`, async (req, res, next) => {
|
|
81
|
+
try {
|
|
82
|
+
const { email, password, firstName, lastName, phone, tenant, roleName, inviteToken, authMode = "jwt" } = req.body;
|
|
83
|
+
if (!email || !password || !firstName) {
|
|
84
|
+
return res.status(400).json({ message: "Email, password, and firstName are required" });
|
|
85
|
+
}
|
|
86
|
+
const ipAddress = req.ip || req.connection?.remoteAddress || null;
|
|
87
|
+
const userAgent = req.headers["user-agent"] || null;
|
|
88
|
+
const result = await auth.signUp({
|
|
89
|
+
email,
|
|
90
|
+
password,
|
|
91
|
+
firstName,
|
|
92
|
+
lastName,
|
|
93
|
+
phone,
|
|
94
|
+
tenant,
|
|
95
|
+
roleName,
|
|
96
|
+
inviteToken,
|
|
97
|
+
ipAddress,
|
|
98
|
+
userAgent,
|
|
99
|
+
});
|
|
100
|
+
// Check if email verification is required
|
|
101
|
+
if (result.requiresEmailVerification) {
|
|
102
|
+
// Don't send token - user needs to verify email first
|
|
103
|
+
return res.json({
|
|
104
|
+
message: "User registered successfully. Please verify your email to login.",
|
|
105
|
+
requiresEmailVerification: true,
|
|
106
|
+
user: {
|
|
107
|
+
id: result.user.id,
|
|
108
|
+
email: result.user.email,
|
|
109
|
+
firstName: result.user.firstName,
|
|
110
|
+
lastName: result.user.lastName,
|
|
111
|
+
},
|
|
112
|
+
role: result.role,
|
|
113
|
+
permissions: result.permissions,
|
|
114
|
+
tenant: result.tenant,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// Set token in response based on authMode
|
|
118
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
119
|
+
res.json({
|
|
120
|
+
message: "User registered successfully",
|
|
121
|
+
...tokenResponse,
|
|
122
|
+
user: {
|
|
123
|
+
id: result.user.id,
|
|
124
|
+
email: result.user.email,
|
|
125
|
+
firstName: result.user.firstName,
|
|
126
|
+
lastName: result.user.lastName,
|
|
127
|
+
},
|
|
128
|
+
role: result.role,
|
|
129
|
+
permissions: result.permissions,
|
|
130
|
+
tenant: result.tenant,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error.message === "User already exists") {
|
|
135
|
+
return res.status(400).json({ message: error.message });
|
|
136
|
+
}
|
|
137
|
+
if (error.message.includes("Tenant information is required")) {
|
|
138
|
+
return res.status(400).json({ message: error.message });
|
|
139
|
+
}
|
|
140
|
+
if (error.message.includes("Invalid or expired invitation")) {
|
|
141
|
+
return res.status(400).json({ message: error.message });
|
|
142
|
+
}
|
|
143
|
+
if (error.message.includes("email address doesn't match")) {
|
|
144
|
+
return res.status(400).json({ message: error.message });
|
|
145
|
+
}
|
|
146
|
+
next(error);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// ==================== Login ====================
|
|
150
|
+
app.post(`${basePath}/login`, async (req, res, next) => {
|
|
151
|
+
try {
|
|
152
|
+
const { email, password, tenant_Id, authType, authMode = "jwt" } = req.body;
|
|
153
|
+
if (!email || !password) {
|
|
154
|
+
return res.status(400).json({ message: "Email and password are required" });
|
|
155
|
+
}
|
|
156
|
+
const ipAddress = req.ip || req.connection?.remoteAddress || null;
|
|
157
|
+
const userAgent = req.headers["user-agent"] || null;
|
|
158
|
+
const result = await auth.signIn({
|
|
159
|
+
email,
|
|
160
|
+
password,
|
|
161
|
+
tenant_Id,
|
|
162
|
+
authType,
|
|
163
|
+
ipAddress,
|
|
164
|
+
userAgent,
|
|
165
|
+
});
|
|
166
|
+
// Set token in response based on authMode
|
|
167
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
168
|
+
res.json({
|
|
169
|
+
...tokenResponse,
|
|
170
|
+
user: {
|
|
171
|
+
id: result.user.id,
|
|
172
|
+
email: result.user.email,
|
|
173
|
+
firstName: result.user.firstName,
|
|
174
|
+
lastName: result.user.lastName,
|
|
175
|
+
},
|
|
176
|
+
role: result.role,
|
|
177
|
+
permissions: result.permissions,
|
|
178
|
+
tenant: result.tenant,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
if (error.message === "Invalid credentials") {
|
|
183
|
+
return res.status(400).json({ message: "Incorrect password." });
|
|
184
|
+
}
|
|
185
|
+
if (error.message.includes("Email not verified")) {
|
|
186
|
+
return res.status(403).json({ message: error.message, requiresEmailVerification: true });
|
|
187
|
+
}
|
|
188
|
+
if (error.message.includes("Account is")) {
|
|
189
|
+
return res.status(403).json({ message: error.message });
|
|
190
|
+
}
|
|
191
|
+
if (error.message.includes("session limit") || error.message.includes("sessions are not allowed")) {
|
|
192
|
+
return res.status(403).json({ message: error.message });
|
|
193
|
+
}
|
|
194
|
+
if (error.message.includes("Invalid session type")) {
|
|
195
|
+
return res.status(403).json({ message: error.message });
|
|
196
|
+
}
|
|
197
|
+
next(error);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
// ==================== Get Current User ====================
|
|
201
|
+
app.get(`${basePath}/me`, async (req, res, next) => {
|
|
202
|
+
try {
|
|
203
|
+
if (!req.accountability?.user) {
|
|
204
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
205
|
+
}
|
|
206
|
+
const user = await auth.getUserById(req.accountability.user.id);
|
|
207
|
+
if (!user) {
|
|
208
|
+
return res.status(404).json({ message: "User not found" });
|
|
209
|
+
}
|
|
210
|
+
// Update last access
|
|
211
|
+
await auth.updateUser(user.id, { lastAccess: new Date() });
|
|
212
|
+
res.json({
|
|
213
|
+
user,
|
|
214
|
+
role: req.accountability.role,
|
|
215
|
+
permissions: req.accountability.permissions,
|
|
216
|
+
tenant: req.accountability.tenant,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
next(error);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
// ==================== Logout ====================
|
|
224
|
+
app.get(`${basePath}/logout`, async (req, res, next) => {
|
|
225
|
+
try {
|
|
226
|
+
const token = req.headers.authorization?.replace("Bearer ", "") || req.cookies?.token;
|
|
227
|
+
if (token) {
|
|
228
|
+
await auth.invalidateSession(token);
|
|
229
|
+
}
|
|
230
|
+
res.clearCookie("token");
|
|
231
|
+
res.json({ message: "Logged out successfully" });
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
next(error);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
// ==================== Social Sign In ====================
|
|
238
|
+
app.post(`${basePath}/social/signin`, async (req, res, next) => {
|
|
239
|
+
try {
|
|
240
|
+
const { provider, callbackURL, errorCallbackURL, scopes, idToken, authMode = "jwt" } = req.body;
|
|
241
|
+
if (!provider) {
|
|
242
|
+
return res.status(400).json({ message: "Provider is required" });
|
|
243
|
+
}
|
|
244
|
+
// If ID token is provided, handle direct sign-in
|
|
245
|
+
if (idToken?.token) {
|
|
246
|
+
const providerInstance = auth.providers.get(provider);
|
|
247
|
+
if (!providerInstance) {
|
|
248
|
+
return res.status(400).json({ message: `Provider '${provider}' not found` });
|
|
249
|
+
}
|
|
250
|
+
// Verify ID token if provider supports it
|
|
251
|
+
if (providerInstance.verifyIdToken) {
|
|
252
|
+
const isValid = await providerInstance.verifyIdToken(idToken.token, idToken.nonce);
|
|
253
|
+
if (!isValid) {
|
|
254
|
+
return res.status(400).json({ message: "Invalid ID token" });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Get user info from ID token
|
|
258
|
+
const tokens = {
|
|
259
|
+
idToken: idToken.token,
|
|
260
|
+
accessToken: idToken.accessToken,
|
|
261
|
+
refreshToken: idToken.refreshToken,
|
|
262
|
+
};
|
|
263
|
+
const userInfo = await providerInstance.getUserInfo(tokens);
|
|
264
|
+
if (!userInfo) {
|
|
265
|
+
return res.status(400).json({ message: "Failed to get user info from token" });
|
|
266
|
+
}
|
|
267
|
+
// Handle OAuth user (create or update)
|
|
268
|
+
// This is simplified - in production you'd want to reuse handleOAuthCallback logic
|
|
269
|
+
const result = await auth.handleOAuthCallback(provider, "", // no code needed
|
|
270
|
+
"", // no state needed
|
|
271
|
+
"", // no code verifier needed
|
|
272
|
+
"" // no redirect URI needed
|
|
273
|
+
);
|
|
274
|
+
// Set token in response based on authMode
|
|
275
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
276
|
+
return res.json({
|
|
277
|
+
redirect: false,
|
|
278
|
+
...tokenResponse,
|
|
279
|
+
user: result.user,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// Generate OAuth URL
|
|
283
|
+
const redirectURI = callbackURL || `${options.baseURL || ""}${basePath}/callback/${provider}`;
|
|
284
|
+
const { url, state, codeVerifier } = await auth.getOAuthUrl(provider, redirectURI, scopes);
|
|
285
|
+
// Store state for verification (including authMode for callback)
|
|
286
|
+
await storeOAuthState(state, { codeVerifier, redirectURI, authMode });
|
|
287
|
+
res.json({
|
|
288
|
+
redirect: true,
|
|
289
|
+
url,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
if (error.message.includes("not found")) {
|
|
294
|
+
return res.status(400).json({ message: error.message });
|
|
295
|
+
}
|
|
296
|
+
next(error);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
// ==================== OAuth Callback ====================
|
|
300
|
+
app.get(`${basePath}/callback/:provider`, async (req, res, next) => {
|
|
301
|
+
try {
|
|
302
|
+
const { provider } = req.params;
|
|
303
|
+
const { code, state, error, error_description } = req.query;
|
|
304
|
+
// Handle OAuth error
|
|
305
|
+
if (error) {
|
|
306
|
+
return res.status(400).json({
|
|
307
|
+
message: error_description || error || "OAuth authentication failed"
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (!code || !state) {
|
|
311
|
+
return res.status(400).json({ message: "Missing code or state parameter" });
|
|
312
|
+
}
|
|
313
|
+
// Get stored state data
|
|
314
|
+
const stateData = await getOAuthState(state);
|
|
315
|
+
if (!stateData) {
|
|
316
|
+
return res.status(400).json({ message: "Invalid or expired state" });
|
|
317
|
+
}
|
|
318
|
+
const { codeVerifier, redirectURI, authMode = "jwt" } = stateData;
|
|
319
|
+
const result = await auth.handleOAuthCallback(provider, code, state, codeVerifier, redirectURI);
|
|
320
|
+
// Set token in response based on authMode
|
|
321
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
322
|
+
// Return JSON response with token
|
|
323
|
+
res.json({
|
|
324
|
+
...tokenResponse,
|
|
325
|
+
user: {
|
|
326
|
+
id: result.user.id,
|
|
327
|
+
email: result.user.email,
|
|
328
|
+
firstName: result.user.firstName,
|
|
329
|
+
lastName: result.user.lastName,
|
|
330
|
+
},
|
|
331
|
+
role: result.role,
|
|
332
|
+
permissions: result.permissions,
|
|
333
|
+
tenant: result.tenant,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
next(error);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
// Apple Sign In POST callback (Apple sends POST with form data)
|
|
341
|
+
app.post(`${basePath}/callback/apple`, async (req, res, next) => {
|
|
342
|
+
try {
|
|
343
|
+
const { code, state, error, id_token, user } = req.body;
|
|
344
|
+
if (error) {
|
|
345
|
+
return res.status(400).json({ message: "Apple authentication failed" });
|
|
346
|
+
}
|
|
347
|
+
if (!code || !state) {
|
|
348
|
+
return res.status(400).json({ message: "Missing code or state parameter" });
|
|
349
|
+
}
|
|
350
|
+
// Get stored state data
|
|
351
|
+
const stateData = await getOAuthState(state);
|
|
352
|
+
if (!stateData) {
|
|
353
|
+
return res.status(400).json({ message: "Invalid or expired state" });
|
|
354
|
+
}
|
|
355
|
+
const { codeVerifier, redirectURI, authMode = "jwt" } = stateData;
|
|
356
|
+
const result = await auth.handleOAuthCallback("apple", code, state, codeVerifier, redirectURI);
|
|
357
|
+
// Set token in response based on authMode
|
|
358
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
359
|
+
res.json({
|
|
360
|
+
...tokenResponse,
|
|
361
|
+
user: {
|
|
362
|
+
id: result.user.id,
|
|
363
|
+
email: result.user.email,
|
|
364
|
+
firstName: result.user.firstName,
|
|
365
|
+
lastName: result.user.lastName,
|
|
366
|
+
},
|
|
367
|
+
role: result.role,
|
|
368
|
+
permissions: result.permissions,
|
|
369
|
+
tenant: result.tenant,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
next(error);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
// ==================== Magic Link ====================
|
|
377
|
+
app.post(`${basePath}/magiclink`, async (req, res, next) => {
|
|
378
|
+
try {
|
|
379
|
+
const { email, link, mode = "link" } = req.body;
|
|
380
|
+
if (!email) {
|
|
381
|
+
return res.status(400).json({ message: "Email is required" });
|
|
382
|
+
}
|
|
383
|
+
if (mode === "link" && !(await isValidAppUrl(link))) {
|
|
384
|
+
return res.status(400).json({ message: "Invalid link" });
|
|
385
|
+
}
|
|
386
|
+
// Check if user exists
|
|
387
|
+
const user = await auth.getUserByEmail(email);
|
|
388
|
+
if (!user) {
|
|
389
|
+
return res.status(404).json({ message: "User not found" });
|
|
390
|
+
}
|
|
391
|
+
// Create magic link token
|
|
392
|
+
const { token, expiresAt } = await auth.createMagicLink(email);
|
|
393
|
+
// Send email
|
|
394
|
+
if (options.mailService) {
|
|
395
|
+
if (mode === "link") {
|
|
396
|
+
const magicLinkUrl = `${link}/auth/magiclink/${token}`;
|
|
397
|
+
await options.mailService.sendMail({
|
|
398
|
+
to: email,
|
|
399
|
+
subject: "Sign in to Your App",
|
|
400
|
+
templateName: "magicLinkUrl",
|
|
401
|
+
context: {
|
|
402
|
+
magicLinkUrl,
|
|
403
|
+
name: user.firstName || user.email,
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
else if (mode === "code") {
|
|
408
|
+
// For code mode, generate a short code and store it separately
|
|
409
|
+
const code = token.substring(0, 12).toUpperCase();
|
|
410
|
+
// Update the verification to store the code as the value
|
|
411
|
+
await auth.updateMagicLinkToken(email, code);
|
|
412
|
+
await options.mailService.sendMail({
|
|
413
|
+
to: email,
|
|
414
|
+
subject: "Sign in to Your App",
|
|
415
|
+
templateName: "magicLinkCode",
|
|
416
|
+
context: {
|
|
417
|
+
code,
|
|
418
|
+
name: user.firstName || user.email,
|
|
419
|
+
},
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
res.json({ message: "Instruction sent to your email" });
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
next(error);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
app.get(`${basePath}/magiclink/:token`, async (req, res, next) => {
|
|
430
|
+
try {
|
|
431
|
+
const { token } = req.params;
|
|
432
|
+
const authMode = req.query.authMode || "jwt";
|
|
433
|
+
const result = await auth.verifyMagicLink(token);
|
|
434
|
+
if (!result) {
|
|
435
|
+
return res.status(400).json({ message: "Invalid or expired token" });
|
|
436
|
+
}
|
|
437
|
+
// Set token in response based on authMode
|
|
438
|
+
const tokenResponse = setTokenInResponse(res, result.token, authMode, options.env);
|
|
439
|
+
res.json({
|
|
440
|
+
...tokenResponse,
|
|
441
|
+
user: {
|
|
442
|
+
id: result.user.id,
|
|
443
|
+
email: result.user.email,
|
|
444
|
+
firstName: result.user.firstName,
|
|
445
|
+
lastName: result.user.lastName,
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
next(error);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
// ==================== Password Reset ====================
|
|
454
|
+
app.post(`${basePath}/password/reset`, async (req, res, next) => {
|
|
455
|
+
try {
|
|
456
|
+
const { email, link } = req.body;
|
|
457
|
+
if (!email) {
|
|
458
|
+
return res.status(400).json({ message: "Email is required" });
|
|
459
|
+
}
|
|
460
|
+
if (!(await isValidAppUrl(link))) {
|
|
461
|
+
return res.status(400).json({ message: "Invalid link" });
|
|
462
|
+
}
|
|
463
|
+
// Check if user exists
|
|
464
|
+
const user = await auth.getUserByEmail(email);
|
|
465
|
+
if (!user) {
|
|
466
|
+
// Don't reveal if user exists
|
|
467
|
+
return res.json({ message: "If an account exists, a reset link will be sent" });
|
|
468
|
+
}
|
|
469
|
+
// Create reset token
|
|
470
|
+
const { token, expiresAt } = await auth.createPasswordReset(email);
|
|
471
|
+
// Send email
|
|
472
|
+
if (options.mailService) {
|
|
473
|
+
const resetUrl = `${link}/auth/reset-password/${token}`;
|
|
474
|
+
await options.mailService.sendMail({
|
|
475
|
+
to: email,
|
|
476
|
+
subject: "Reset Your Password",
|
|
477
|
+
templateName: "passwordReset",
|
|
478
|
+
context: {
|
|
479
|
+
resetUrl,
|
|
480
|
+
name: user.firstName || user.email,
|
|
481
|
+
expiresAt: expiresAt.toISOString(),
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
res.json({ message: "If an account exists, a reset link will be sent" });
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
next(error);
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
app.post(`${basePath}/password/reset/:token`, async (req, res, next) => {
|
|
492
|
+
try {
|
|
493
|
+
const { token } = req.params;
|
|
494
|
+
const { password } = req.body;
|
|
495
|
+
if (!password) {
|
|
496
|
+
return res.status(400).json({ message: "Password is required" });
|
|
497
|
+
}
|
|
498
|
+
const success = await auth.verifyPasswordReset(token, password);
|
|
499
|
+
if (!success) {
|
|
500
|
+
return res.status(400).json({ message: "Invalid or expired token" });
|
|
501
|
+
}
|
|
502
|
+
res.json({ message: "Password reset successfully" });
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
if (error.message.includes("Password must")) {
|
|
506
|
+
return res.status(400).json({ message: error.message });
|
|
507
|
+
}
|
|
508
|
+
next(error);
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
// ==================== Change Password ====================
|
|
512
|
+
app.post(`${basePath}/password/change`, async (req, res, next) => {
|
|
513
|
+
try {
|
|
514
|
+
if (!req.accountability?.user) {
|
|
515
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
516
|
+
}
|
|
517
|
+
const { currentPassword, newPassword } = req.body;
|
|
518
|
+
if (!currentPassword || !newPassword) {
|
|
519
|
+
return res.status(400).json({ message: "Current and new password are required" });
|
|
520
|
+
}
|
|
521
|
+
const success = await auth.changePassword(req.accountability.user.id, currentPassword, newPassword);
|
|
522
|
+
if (!success) {
|
|
523
|
+
return res.status(400).json({ message: "Failed to change password" });
|
|
524
|
+
}
|
|
525
|
+
res.json({ message: "Password changed successfully" });
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
if (error.message.includes("Password")) {
|
|
529
|
+
return res.status(400).json({ message: error.message });
|
|
530
|
+
}
|
|
531
|
+
next(error);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
// ==================== Admin Change Password ====================
|
|
535
|
+
app.post(`${basePath}/admin/password/change`, async (req, res, next) => {
|
|
536
|
+
try {
|
|
537
|
+
if (!req.accountability?.user) {
|
|
538
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
539
|
+
}
|
|
540
|
+
// Check if user has admin role using shared isAdmin function
|
|
541
|
+
if (!isAdmin(req)) {
|
|
542
|
+
return res.status(403).json({ message: "Only administrators can change other users' passwords" });
|
|
543
|
+
}
|
|
544
|
+
const { userId, newPassword } = req.body;
|
|
545
|
+
if (!userId || !newPassword) {
|
|
546
|
+
return res.status(400).json({ message: "User ID and new password are required" });
|
|
547
|
+
}
|
|
548
|
+
// Verify target user exists
|
|
549
|
+
const targetUser = await auth.getUserById(userId);
|
|
550
|
+
if (!targetUser) {
|
|
551
|
+
return res.status(404).json({ message: "User not found" });
|
|
552
|
+
}
|
|
553
|
+
const success = await auth.resetPassword(userId, newPassword);
|
|
554
|
+
if (!success) {
|
|
555
|
+
return res.status(400).json({ message: "Failed to change password" });
|
|
556
|
+
}
|
|
557
|
+
res.json({ message: "Password changed successfully" });
|
|
558
|
+
}
|
|
559
|
+
catch (error) {
|
|
560
|
+
if (error.message.includes("Password")) {
|
|
561
|
+
return res.status(400).json({ message: error.message });
|
|
562
|
+
}
|
|
563
|
+
next(error);
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
// ==================== Email Verification ====================
|
|
567
|
+
app.post(`${basePath}/email/verify`, async (req, res, next) => {
|
|
568
|
+
try {
|
|
569
|
+
if (!req.accountability?.user) {
|
|
570
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
571
|
+
}
|
|
572
|
+
const { link } = req.body;
|
|
573
|
+
if (!(await isValidAppUrl(link))) {
|
|
574
|
+
return res.status(400).json({ message: "Invalid link" });
|
|
575
|
+
}
|
|
576
|
+
const user = await auth.getUserById(req.accountability.user.id);
|
|
577
|
+
if (!user || !user.email) {
|
|
578
|
+
return res.status(400).json({ message: "User not found or no email set" });
|
|
579
|
+
}
|
|
580
|
+
if (user.emailVerified) {
|
|
581
|
+
return res.json({ message: "Email already verified" });
|
|
582
|
+
}
|
|
583
|
+
// Create verification token
|
|
584
|
+
const { token, expiresAt } = await auth.createEmailVerification(user.email);
|
|
585
|
+
// Send email
|
|
586
|
+
if (options.mailService) {
|
|
587
|
+
const verifyUrl = `${link}/auth/verify-email/${token}`;
|
|
588
|
+
await options.mailService.sendMail({
|
|
589
|
+
to: user.email,
|
|
590
|
+
subject: "Verify Your Email",
|
|
591
|
+
templateName: "emailVerification",
|
|
592
|
+
context: {
|
|
593
|
+
verifyUrl,
|
|
594
|
+
name: user.firstName || user.email,
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
res.json({ message: "Verification email sent" });
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
next(error);
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
app.get(`${basePath}/email/verify/:token`, async (req, res, next) => {
|
|
605
|
+
try {
|
|
606
|
+
const { token } = req.params;
|
|
607
|
+
const user = await auth.verifyEmail(token);
|
|
608
|
+
if (!user) {
|
|
609
|
+
return res.status(400).json({ message: "Invalid or expired token" });
|
|
610
|
+
}
|
|
611
|
+
res.json({ message: "Email verified successfully", user });
|
|
612
|
+
}
|
|
613
|
+
catch (error) {
|
|
614
|
+
next(error);
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
// ==================== Session Check ====================
|
|
618
|
+
app.get(`${basePath}/check`, async (req, res) => {
|
|
619
|
+
try {
|
|
620
|
+
const token = req.headers.authorization?.replace("Bearer ", "") || req.cookies?.token;
|
|
621
|
+
if (!token) {
|
|
622
|
+
return res.status(401).json({
|
|
623
|
+
valid: false,
|
|
624
|
+
message: "No token provided",
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
const result = await auth.validateSession(token);
|
|
628
|
+
if (!result) {
|
|
629
|
+
return res.status(401).json({
|
|
630
|
+
valid: false,
|
|
631
|
+
message: "Invalid or expired token",
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
res.json({
|
|
635
|
+
valid: true,
|
|
636
|
+
user: { id: result.user.id },
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
catch (error) {
|
|
640
|
+
res.status(401).json({
|
|
641
|
+
valid: false,
|
|
642
|
+
message: "Invalid or expired token",
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
// ==================== Get Tenants ====================
|
|
647
|
+
app.get(`${basePath}/tenants`, async (req, res, next) => {
|
|
648
|
+
try {
|
|
649
|
+
const isMultiTenant = options.multiTenant?.enabled || options.env?.get("MULTI_TENANT") === "true";
|
|
650
|
+
if (!isMultiTenant) {
|
|
651
|
+
return res.status(400).json({ message: "Multi-tenant mode is not enabled" });
|
|
652
|
+
}
|
|
653
|
+
if (!req.accountability?.user) {
|
|
654
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
655
|
+
}
|
|
656
|
+
// Get all user roles with their tenants
|
|
657
|
+
const userRoles = await auth.adapter.findUserRolesByUserId(req.accountability.user.id);
|
|
658
|
+
// Filter to get only tenant-specific roles
|
|
659
|
+
const tenants = [];
|
|
660
|
+
for (const ur of userRoles) {
|
|
661
|
+
if (ur.tenant_Id && ur.role?.isTenantSpecific) {
|
|
662
|
+
const tenant = await auth.adapter.findTenantById(ur.tenant_Id);
|
|
663
|
+
if (tenant) {
|
|
664
|
+
tenants.push({
|
|
665
|
+
id: tenant.id,
|
|
666
|
+
name: tenant.name,
|
|
667
|
+
role: {
|
|
668
|
+
id: ur.role.id,
|
|
669
|
+
name: ur.role.name,
|
|
670
|
+
},
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
res.json({ tenants });
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
next(error);
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
// ==================== Switch Tenant ====================
|
|
682
|
+
app.post(`${basePath}/switch-tenant`, async (req, res, next) => {
|
|
683
|
+
try {
|
|
684
|
+
const isMultiTenant = options.multiTenant?.enabled || options.env?.get("MULTI_TENANT") === "true";
|
|
685
|
+
if (!isMultiTenant) {
|
|
686
|
+
return res.status(400).json({ message: "Multi-tenant mode is not enabled" });
|
|
687
|
+
}
|
|
688
|
+
if (!req.accountability?.user) {
|
|
689
|
+
return res.status(401).json({ message: "Unauthorized" });
|
|
690
|
+
}
|
|
691
|
+
const { tenant_Id, authType, authMode = "jwt" } = req.body;
|
|
692
|
+
if (!tenant_Id) {
|
|
693
|
+
return res.status(400).json({ message: "Tenant ID is required" });
|
|
694
|
+
}
|
|
695
|
+
// Get user role for the specified tenant
|
|
696
|
+
const userRoles = await auth.adapter.findUserRolesByUserId(req.accountability.user.id, tenant_Id);
|
|
697
|
+
if (!userRoles || userRoles.length === 0) {
|
|
698
|
+
return res.status(403).json({ message: "Access denied for specified tenant" });
|
|
699
|
+
}
|
|
700
|
+
const userRole = userRoles[0];
|
|
701
|
+
if (!userRole.role?.isTenantSpecific) {
|
|
702
|
+
return res.status(400).json({ message: "Cannot switch tenant for non-tenant-specific role" });
|
|
703
|
+
}
|
|
704
|
+
// Get updated role and permissions
|
|
705
|
+
const { role, permissions, tenant } = await auth.getUserRoleAndPermissions(req.accountability.user.id, tenant_Id);
|
|
706
|
+
if (!tenant) {
|
|
707
|
+
return res.status(404).json({ message: "Tenant not found" });
|
|
708
|
+
}
|
|
709
|
+
// Validate session limits if authType is specified
|
|
710
|
+
if (authType && authType !== "default") {
|
|
711
|
+
const { validateSessionLimits } = await import("../utils/auth.js");
|
|
712
|
+
const validation = await validateSessionLimits(req.accountability.user.id, authType, tenant.id, role);
|
|
713
|
+
if (!validation.isValid) {
|
|
714
|
+
return res.status(403).json({ message: validation.error });
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
// Create new session
|
|
718
|
+
const ipAddress = req.ip || req.connection?.remoteAddress || null;
|
|
719
|
+
const userAgent = req.headers["user-agent"] || null;
|
|
720
|
+
const session = await auth.sessionService.createSession({
|
|
721
|
+
user: req.accountability.user,
|
|
722
|
+
tenantId: tenant.id,
|
|
723
|
+
ipAddress,
|
|
724
|
+
userAgent,
|
|
725
|
+
type: authType || "default",
|
|
726
|
+
});
|
|
727
|
+
// Generate new token
|
|
728
|
+
const token = auth.tokenService.generateUserToken({
|
|
729
|
+
user: req.accountability.user,
|
|
730
|
+
role,
|
|
731
|
+
session,
|
|
732
|
+
tenant,
|
|
733
|
+
});
|
|
734
|
+
// Set token in response based on authMode
|
|
735
|
+
const tokenResponse = setTokenInResponse(res, token, authMode, options.env);
|
|
736
|
+
res.json({
|
|
737
|
+
...tokenResponse,
|
|
738
|
+
user: {
|
|
739
|
+
id: req.accountability.user.id,
|
|
740
|
+
email: req.accountability.user.email,
|
|
741
|
+
firstName: req.accountability.user.firstName,
|
|
742
|
+
lastName: req.accountability.user.lastName,
|
|
743
|
+
},
|
|
744
|
+
role,
|
|
745
|
+
permissions,
|
|
746
|
+
tenant,
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
catch (error) {
|
|
750
|
+
next(error);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
return auth;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Create auth middleware for Express
|
|
757
|
+
*/
|
|
758
|
+
export function createAuthMiddleware(auth) {
|
|
759
|
+
return async (req, res, next) => {
|
|
760
|
+
try {
|
|
761
|
+
// Extract token
|
|
762
|
+
let token = req.headers.authorization?.replace("Bearer ", "");
|
|
763
|
+
if (!token && req.cookies?.token) {
|
|
764
|
+
token = req.cookies.token;
|
|
765
|
+
}
|
|
766
|
+
if (!token && req.query?.access_token) {
|
|
767
|
+
token = req.query.access_token;
|
|
768
|
+
}
|
|
769
|
+
if (!token && req.body?.access_token) {
|
|
770
|
+
token = req.body.access_token;
|
|
771
|
+
}
|
|
772
|
+
if (!token) {
|
|
773
|
+
// No token - treat as public access
|
|
774
|
+
const publicRole = await getPublicRole();
|
|
775
|
+
req.accountability = {
|
|
776
|
+
user: null,
|
|
777
|
+
role: publicRole,
|
|
778
|
+
permissions: [],
|
|
779
|
+
tenant: null,
|
|
780
|
+
ipaddress: req.ip || req.connection?.remoteAddress,
|
|
781
|
+
};
|
|
782
|
+
return next();
|
|
783
|
+
}
|
|
784
|
+
// Validate session
|
|
785
|
+
const result = await auth.validateSession(token);
|
|
786
|
+
if (!result) {
|
|
787
|
+
const publicRole = await getPublicRole();
|
|
788
|
+
req.accountability = {
|
|
789
|
+
user: null,
|
|
790
|
+
role: publicRole,
|
|
791
|
+
permissions: [],
|
|
792
|
+
tenant: null,
|
|
793
|
+
ipaddress: req.ip || req.connection?.remoteAddress,
|
|
794
|
+
};
|
|
795
|
+
return next();
|
|
796
|
+
}
|
|
797
|
+
const { user, role, permissions, tenant } = result;
|
|
798
|
+
req.accountability = {
|
|
799
|
+
user: {
|
|
800
|
+
...user,
|
|
801
|
+
isAdmin: role.name === "administrator",
|
|
802
|
+
role: role.name,
|
|
803
|
+
},
|
|
804
|
+
role: role,
|
|
805
|
+
permissions,
|
|
806
|
+
tenant: tenant?.id || null,
|
|
807
|
+
ipaddress: req.ip || req.connection?.remoteAddress,
|
|
808
|
+
};
|
|
809
|
+
next();
|
|
810
|
+
}
|
|
811
|
+
catch (error) {
|
|
812
|
+
console.error("Auth middleware error:", error);
|
|
813
|
+
// getPublicRole is now async (uses hybrid cache)
|
|
814
|
+
const publicRole = await getPublicRole();
|
|
815
|
+
req.accountability = {
|
|
816
|
+
user: null,
|
|
817
|
+
role: publicRole,
|
|
818
|
+
permissions: [],
|
|
819
|
+
tenant: null,
|
|
820
|
+
ipaddress: req.ip || req.connection?.remoteAddress,
|
|
821
|
+
};
|
|
822
|
+
next();
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
export default { createAuthRoutes, createAuthMiddleware };
|
|
827
|
+
//# sourceMappingURL=routes.js.map
|