@zeitvu97/cms-sdk 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 +21 -0
- package/README.md +478 -0
- package/dist/chunks/_shared-48T7q0V3.js +26 -0
- package/dist/chunks/_shared-48T7q0V3.js.map +1 -0
- package/dist/chunks/auth.constant-DO7ZmsKg.js +68 -0
- package/dist/chunks/auth.constant-DO7ZmsKg.js.map +1 -0
- package/dist/chunks/mt5Retcode-DlZLQOLA.js +178 -0
- package/dist/chunks/mt5Retcode-DlZLQOLA.js.map +1 -0
- package/dist/chunks/storage.constant--64BDSPW.js +44 -0
- package/dist/chunks/storage.constant--64BDSPW.js.map +1 -0
- package/dist/common/constants/auth.constant.d.ts +54 -0
- package/dist/common/constants/auth.constant.d.ts.map +1 -0
- package/dist/common/constants/bars.constant.d.ts +15 -0
- package/dist/common/constants/bars.constant.d.ts.map +1 -0
- package/dist/common/constants/content-types.constant.d.ts +29 -0
- package/dist/common/constants/content-types.constant.d.ts.map +1 -0
- package/dist/common/constants/content.constant.d.ts +114 -0
- package/dist/common/constants/content.constant.d.ts.map +1 -0
- package/dist/common/constants/executions.constant.d.ts +56 -0
- package/dist/common/constants/executions.constant.d.ts.map +1 -0
- package/dist/common/constants/gov.constant.d.ts +118 -0
- package/dist/common/constants/gov.constant.d.ts.map +1 -0
- package/dist/common/constants/history.constant.d.ts +108 -0
- package/dist/common/constants/history.constant.d.ts.map +1 -0
- package/dist/common/constants/http.constant.d.ts +46 -0
- package/dist/common/constants/http.constant.d.ts.map +1 -0
- package/dist/common/constants/index.d.ts +16 -0
- package/dist/common/constants/index.d.ts.map +1 -0
- package/dist/common/constants/kalshi.constant.d.ts +35 -0
- package/dist/common/constants/kalshi.constant.d.ts.map +1 -0
- package/dist/common/constants/llm.constant.d.ts +37 -0
- package/dist/common/constants/llm.constant.d.ts.map +1 -0
- package/dist/common/constants/mt5-action.constant.d.ts +131 -0
- package/dist/common/constants/mt5-action.constant.d.ts.map +1 -0
- package/dist/common/constants/mt5.constant.d.ts +254 -0
- package/dist/common/constants/mt5.constant.d.ts.map +1 -0
- package/dist/common/constants/notifications.constant.d.ts +45 -0
- package/dist/common/constants/notifications.constant.d.ts.map +1 -0
- package/dist/common/constants/people.constant.d.ts +269 -0
- package/dist/common/constants/people.constant.d.ts.map +1 -0
- package/dist/common/constants/rules.constant.d.ts +14 -0
- package/dist/common/constants/rules.constant.d.ts.map +1 -0
- package/dist/common/constants/settings.constant.d.ts +17 -0
- package/dist/common/constants/settings.constant.d.ts.map +1 -0
- package/dist/common/constants/sort.constant.d.ts +14 -0
- package/dist/common/constants/sort.constant.d.ts.map +1 -0
- package/dist/common/constants/storage.constant.d.ts +74 -0
- package/dist/common/constants/storage.constant.d.ts.map +1 -0
- package/dist/common/helpers/format.d.ts +7 -0
- package/dist/common/helpers/format.d.ts.map +1 -0
- package/dist/common/helpers/format.js +20 -0
- package/dist/common/helpers/format.js.map +1 -0
- package/dist/common/helpers/mt5Retcode.d.ts +18 -0
- package/dist/common/helpers/mt5Retcode.d.ts.map +1 -0
- package/dist/common/helpers/mt5Retcode.js +2 -0
- package/dist/common/helpers/mt5Retcode.js.map +1 -0
- package/dist/common/utils/case.d.ts +12 -0
- package/dist/common/utils/case.d.ts.map +1 -0
- package/dist/common/utils/clone.d.ts +9 -0
- package/dist/common/utils/clone.d.ts.map +1 -0
- package/dist/composables/cbsStateKey.d.ts +27 -0
- package/dist/composables/cbsStateKey.d.ts.map +1 -0
- package/dist/core/createApi.d.ts +69 -0
- package/dist/core/createApi.d.ts.map +1 -0
- package/dist/core/createCmsSDK.d.ts +19 -0
- package/dist/core/createCmsSDK.d.ts.map +1 -0
- package/dist/core/credentials/TokenManager.d.ts +38 -0
- package/dist/core/credentials/TokenManager.d.ts.map +1 -0
- package/dist/core/credentials/credential.type.d.ts +16 -0
- package/dist/core/credentials/credential.type.d.ts.map +1 -0
- package/dist/core/credentials/resolveStorage.d.ts +6 -0
- package/dist/core/credentials/resolveStorage.d.ts.map +1 -0
- package/dist/core/credentials/storages/cookieStorage.d.ts +18 -0
- package/dist/core/credentials/storages/cookieStorage.d.ts.map +1 -0
- package/dist/core/credentials/storages/localStorageAdapter.d.ts +8 -0
- package/dist/core/credentials/storages/localStorageAdapter.d.ts.map +1 -0
- package/dist/core/credentials/storages/memoryStorage.d.ts +7 -0
- package/dist/core/credentials/storages/memoryStorage.d.ts.map +1 -0
- package/dist/core/errors.d.ts +26 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/sdk.type.d.ts +115 -0
- package/dist/core/sdk.type.d.ts.map +1 -0
- package/dist/core/ws/createEaeraWebSocket.d.ts +21 -0
- package/dist/core/ws/createEaeraWebSocket.d.ts.map +1 -0
- package/dist/core/ws/index.d.ts +4 -0
- package/dist/core/ws/index.d.ts.map +1 -0
- package/dist/core/ws/ws.constants.d.ts +246 -0
- package/dist/core/ws/ws.constants.d.ts.map +1 -0
- package/dist/core/ws/ws.events.d.ts +264 -0
- package/dist/core/ws/ws.events.d.ts.map +1 -0
- package/dist/core/ws/ws.type.d.ts +225 -0
- package/dist/core/ws/ws.type.d.ts.map +1 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8416 -0
- package/dist/index.js.map +1 -0
- package/dist/nuxt.d.ts +49 -0
- package/dist/nuxt.d.ts.map +1 -0
- package/dist/nuxt.js +47 -0
- package/dist/nuxt.js.map +1 -0
- package/dist/runtime/plugin.d.ts +6 -0
- package/dist/runtime/plugin.js +188 -0
- package/dist/runtime/plugin.js.map +1 -0
- package/dist/server/auth/cbs-callback.post.js +42 -0
- package/dist/server/auth/cbs-callback.post.js.map +1 -0
- package/dist/server/auth/cbs-start.post.js +34 -0
- package/dist/server/auth/cbs-start.post.js.map +1 -0
- package/dist/server/auth/idp-callback.get.js +52 -0
- package/dist/server/auth/idp-callback.get.js.map +1 -0
- package/dist/server/auth/idp-link.post.js +38 -0
- package/dist/server/auth/idp-link.post.js.map +1 -0
- package/dist/server/auth/idp-login.get.js +42 -0
- package/dist/server/auth/idp-login.get.js.map +1 -0
- package/dist/server/auth/idp-unlink.delete.js +38 -0
- package/dist/server/auth/idp-unlink.delete.js.map +1 -0
- package/dist/server/auth/login.post.js +42 -0
- package/dist/server/auth/login.post.js.map +1 -0
- package/dist/server/auth/logout.post.js +31 -0
- package/dist/server/auth/logout.post.js.map +1 -0
- package/dist/server/auth/refresh.post.js +46 -0
- package/dist/server/auth/refresh.post.js.map +1 -0
- package/dist/server/clear-token.delete.js +12 -0
- package/dist/server/clear-token.delete.js.map +1 -0
- package/dist/server/persist.post.js +31 -0
- package/dist/server/persist.post.js.map +1 -0
- package/dist/server/set-token.post.js +27 -0
- package/dist/server/set-token.post.js.map +1 -0
- package/dist/services/auth/auth.type.d.ts +66 -0
- package/dist/services/auth/auth.type.d.ts.map +1 -0
- package/dist/services/auth/index.d.ts +127 -0
- package/dist/services/auth/index.d.ts.map +1 -0
- package/dist/services/auth/mock.d.ts +13 -0
- package/dist/services/auth/mock.d.ts.map +1 -0
- package/dist/services/bars/bars.type.d.ts +78 -0
- package/dist/services/bars/bars.type.d.ts.map +1 -0
- package/dist/services/bars/index.d.ts +24 -0
- package/dist/services/bars/index.d.ts.map +1 -0
- package/dist/services/bars/mock.d.ts +23 -0
- package/dist/services/bars/mock.d.ts.map +1 -0
- package/dist/services/content/content.type.d.ts +832 -0
- package/dist/services/content/content.type.d.ts.map +1 -0
- package/dist/services/content/filter.d.ts +46 -0
- package/dist/services/content/filter.d.ts.map +1 -0
- package/dist/services/content/index.d.ts +35 -0
- package/dist/services/content/index.d.ts.map +1 -0
- package/dist/services/content/mock.d.ts +16 -0
- package/dist/services/content/mock.d.ts.map +1 -0
- package/dist/services/content-types/content-types.type.d.ts +70 -0
- package/dist/services/content-types/content-types.type.d.ts.map +1 -0
- package/dist/services/content-types/index.d.ts +18 -0
- package/dist/services/content-types/index.d.ts.map +1 -0
- package/dist/services/content-types/mock.d.ts +15 -0
- package/dist/services/content-types/mock.d.ts.map +1 -0
- package/dist/services/executions/executions.type.d.ts +67 -0
- package/dist/services/executions/executions.type.d.ts.map +1 -0
- package/dist/services/executions/index.d.ts +30 -0
- package/dist/services/executions/index.d.ts.map +1 -0
- package/dist/services/executions/mock.d.ts +29 -0
- package/dist/services/executions/mock.d.ts.map +1 -0
- package/dist/services/gov/gov.type.d.ts +740 -0
- package/dist/services/gov/gov.type.d.ts.map +1 -0
- package/dist/services/gov/index.d.ts +84 -0
- package/dist/services/gov/index.d.ts.map +1 -0
- package/dist/services/history/history.type.d.ts +167 -0
- package/dist/services/history/history.type.d.ts.map +1 -0
- package/dist/services/history/index.d.ts +38 -0
- package/dist/services/history/index.d.ts.map +1 -0
- package/dist/services/history/mock.d.ts +21 -0
- package/dist/services/history/mock.d.ts.map +1 -0
- package/dist/services/kalshi/index.d.ts +19 -0
- package/dist/services/kalshi/index.d.ts.map +1 -0
- package/dist/services/kalshi/kalshi.type.d.ts +99 -0
- package/dist/services/kalshi/kalshi.type.d.ts.map +1 -0
- package/dist/services/kalshi/mock.d.ts +5 -0
- package/dist/services/kalshi/mock.d.ts.map +1 -0
- package/dist/services/llm/index.d.ts +38 -0
- package/dist/services/llm/index.d.ts.map +1 -0
- package/dist/services/llm/llm.type.d.ts +106 -0
- package/dist/services/llm/llm.type.d.ts.map +1 -0
- package/dist/services/notifications/index.d.ts +38 -0
- package/dist/services/notifications/index.d.ts.map +1 -0
- package/dist/services/notifications/mock.d.ts +39 -0
- package/dist/services/notifications/mock.d.ts.map +1 -0
- package/dist/services/notifications/notifications.type.d.ts +75 -0
- package/dist/services/notifications/notifications.type.d.ts.map +1 -0
- package/dist/services/people/_invoke.d.ts +26 -0
- package/dist/services/people/_invoke.d.ts.map +1 -0
- package/dist/services/people/copilot/index.d.ts +132 -0
- package/dist/services/people/copilot/index.d.ts.map +1 -0
- package/dist/services/people/identity/actions.d.ts +116 -0
- package/dist/services/people/identity/actions.d.ts.map +1 -0
- package/dist/services/people/identity/ct.types.d.ts +133 -0
- package/dist/services/people/identity/ct.types.d.ts.map +1 -0
- package/dist/services/people/identity/index.d.ts +14 -0
- package/dist/services/people/identity/index.d.ts.map +1 -0
- package/dist/services/people/identity/projections.d.ts +63 -0
- package/dist/services/people/identity/projections.d.ts.map +1 -0
- package/dist/services/people/index.d.ts +31 -0
- package/dist/services/people/index.d.ts.map +1 -0
- package/dist/services/people/legal/actions.d.ts +161 -0
- package/dist/services/people/legal/actions.d.ts.map +1 -0
- package/dist/services/people/legal/ct.types.d.ts +186 -0
- package/dist/services/people/legal/ct.types.d.ts.map +1 -0
- package/dist/services/people/legal/index.d.ts +15 -0
- package/dist/services/people/legal/index.d.ts.map +1 -0
- package/dist/services/people/packops/index.d.ts +70 -0
- package/dist/services/people/packops/index.d.ts.map +1 -0
- package/dist/services/people/packops/packops.type.d.ts +183 -0
- package/dist/services/people/packops/packops.type.d.ts.map +1 -0
- package/dist/services/people/perms/actions.d.ts +214 -0
- package/dist/services/people/perms/actions.d.ts.map +1 -0
- package/dist/services/people/perms/ct.types.d.ts +140 -0
- package/dist/services/people/perms/ct.types.d.ts.map +1 -0
- package/dist/services/people/perms/index.d.ts +14 -0
- package/dist/services/people/perms/index.d.ts.map +1 -0
- package/dist/services/people/perms/projections.d.ts +47 -0
- package/dist/services/people/perms/projections.d.ts.map +1 -0
- package/dist/services/people/process/actions.d.ts +154 -0
- package/dist/services/people/process/actions.d.ts.map +1 -0
- package/dist/services/people/process/ct.types.d.ts +304 -0
- package/dist/services/people/process/ct.types.d.ts.map +1 -0
- package/dist/services/people/process/index.d.ts +12 -0
- package/dist/services/people/process/index.d.ts.map +1 -0
- package/dist/services/people/shared.types.d.ts +36 -0
- package/dist/services/people/shared.types.d.ts.map +1 -0
- package/dist/services/rules/conditions.d.ts +264 -0
- package/dist/services/rules/conditions.d.ts.map +1 -0
- package/dist/services/rules/index.d.ts +49 -0
- package/dist/services/rules/index.d.ts.map +1 -0
- package/dist/services/rules/llm-rule.constant.d.ts +84 -0
- package/dist/services/rules/llm-rule.constant.d.ts.map +1 -0
- package/dist/services/rules/mock.d.ts +20 -0
- package/dist/services/rules/mock.d.ts.map +1 -0
- package/dist/services/rules/rules.type.d.ts +262 -0
- package/dist/services/rules/rules.type.d.ts.map +1 -0
- package/dist/services/rules/triggers.d.ts +140 -0
- package/dist/services/rules/triggers.d.ts.map +1 -0
- package/dist/services/settings/index.d.ts +36 -0
- package/dist/services/settings/index.d.ts.map +1 -0
- package/dist/services/settings/mock.d.ts +14 -0
- package/dist/services/settings/mock.d.ts.map +1 -0
- package/dist/services/settings/settings.type.d.ts +39 -0
- package/dist/services/settings/settings.type.d.ts.map +1 -0
- package/dist/stores/auth.d.ts +192 -0
- package/dist/stores/auth.d.ts.map +1 -0
- package/dist/stores/bars.d.ts +288 -0
- package/dist/stores/bars.d.ts.map +1 -0
- package/dist/stores/content.d.ts +4101 -0
- package/dist/stores/content.d.ts.map +1 -0
- package/dist/stores/executions.d.ts +249 -0
- package/dist/stores/executions.d.ts.map +1 -0
- package/dist/stores/gov.d.ts +238 -0
- package/dist/stores/gov.d.ts.map +1 -0
- package/dist/stores/history.d.ts +833 -0
- package/dist/stores/history.d.ts.map +1 -0
- package/dist/stores/index.d.ts +15 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/kalshi.d.ts +728 -0
- package/dist/stores/kalshi.d.ts.map +1 -0
- package/dist/stores/llm-providers.d.ts +97 -0
- package/dist/stores/llm-providers.d.ts.map +1 -0
- package/dist/stores/llm.d.ts +102 -0
- package/dist/stores/llm.d.ts.map +1 -0
- package/dist/stores/people.d.ts +596 -0
- package/dist/stores/people.d.ts.map +1 -0
- package/dist/stores/persist.d.ts +58 -0
- package/dist/stores/persist.d.ts.map +1 -0
- package/dist/stores/rules.d.ts +485 -0
- package/dist/stores/rules.d.ts.map +1 -0
- package/dist/stores/settings.d.ts +36 -0
- package/dist/stores/settings.d.ts.map +1 -0
- package/dist/stores/ws.d.ts +66 -0
- package/dist/stores/ws.d.ts.map +1 -0
- package/package.json +90 -0
package/dist/nuxt.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { RequestCasing, ResponseCasing } from './common/constants/http.constant';
|
|
2
|
+
import { StorageName } from './common/constants/storage.constant';
|
|
3
|
+
export interface IModuleOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Names of `runtimeConfig.public` keys holding each endpoint URL.
|
|
6
|
+
* Default reads `cmsUrl`, `reportUrl`, `poolTradingUrl`.
|
|
7
|
+
*/
|
|
8
|
+
endpoints?: Record<string, string>;
|
|
9
|
+
clientId?: string;
|
|
10
|
+
/** Storage backend name. Default 'cookie'. */
|
|
11
|
+
storage?: StorageName;
|
|
12
|
+
/** Use fake data until the backend is ready. Default false. */
|
|
13
|
+
mock?: boolean;
|
|
14
|
+
timeout?: number;
|
|
15
|
+
retry?: number;
|
|
16
|
+
/** Response casing to request from the backend (`x-response-casing`). Default camel. */
|
|
17
|
+
responseCasing?: ResponseCasing;
|
|
18
|
+
/** Request casing declared to the backend (`x-request-casing`). Default camel. */
|
|
19
|
+
requestCasing?: RequestCasing;
|
|
20
|
+
/**
|
|
21
|
+
* Topics to subscribe to automatically after the WS connection opens.
|
|
22
|
+
* Server-side permissions still apply (FEAT-010 §5.4).
|
|
23
|
+
*
|
|
24
|
+
* Defaults to `[]` (consumer-driven via `useWsStore().subscribe([...])`).
|
|
25
|
+
*/
|
|
26
|
+
wsTopics?: string[];
|
|
27
|
+
/**
|
|
28
|
+
* Auto-open the WebSocket on app mount (client-only). Default `true`.
|
|
29
|
+
* Set `false` for consumers that prefer explicit `useWsStore().open()`.
|
|
30
|
+
*/
|
|
31
|
+
wsAutoOpen?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Nuxt module: registers a plugin that builds the CMS SDK from runtime
|
|
35
|
+
* config and provides it as `$cms` / `useNuxtApp().$cms`. Also attaches the
|
|
36
|
+
* SDK to the auth Pinia store and installs persistence.
|
|
37
|
+
*
|
|
38
|
+
* Consumer config:
|
|
39
|
+
* ```ts
|
|
40
|
+
* export default defineNuxtConfig({
|
|
41
|
+
* modules: ['@zeitvu97/cms-sdk/nuxt'],
|
|
42
|
+
* runtimeConfig: { public: { cmsUrl: 'https://...', clientId: 'web' } },
|
|
43
|
+
* cmsSdk: { storage: 'cookie', mock: true },
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare const _default: import('@nuxt/schema').NuxtModule<IModuleOptions, IModuleOptions, false>;
|
|
48
|
+
export default _default;
|
|
49
|
+
//# sourceMappingURL=nuxt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kFAAkF;IAClF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;;AACH,wBA+BG"}
|
package/dist/nuxt.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineNuxtModule, useLogger, createResolver, addServerHandler, addPlugin } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const SERVER_HANDLERS = [
|
|
4
|
+
["/api/cms/set-token", "server/set-token.post.js"],
|
|
5
|
+
["/api/cms/clear-token", "server/clear-token.delete.js"],
|
|
6
|
+
["/api/cms/login", "server/auth/login.post.js"],
|
|
7
|
+
["/api/cms/logout", "server/auth/logout.post.js"],
|
|
8
|
+
["/api/cms/refresh", "server/auth/refresh.post.js"],
|
|
9
|
+
["/api/cms/cbs-start", "server/auth/cbs-start.post.js"],
|
|
10
|
+
["/api/cms/cbs-callback", "server/auth/cbs-callback.post.js"],
|
|
11
|
+
["/api/cms/idp-login", "server/auth/idp-login.get.js"],
|
|
12
|
+
["/api/cms/idp-callback", "server/auth/idp-callback.get.js"],
|
|
13
|
+
["/api/cms/idp-link", "server/auth/idp-link.post.js"],
|
|
14
|
+
["/api/cms/idp-unlink", "server/auth/idp-unlink.delete.js"],
|
|
15
|
+
["/api/cms-sdk/persist", "server/persist.post.js"]
|
|
16
|
+
];
|
|
17
|
+
const nuxt = defineNuxtModule({
|
|
18
|
+
meta: {
|
|
19
|
+
name: "@zeitvu97/cms-sdk",
|
|
20
|
+
configKey: "cmsSdk",
|
|
21
|
+
compatibility: { nuxt: "^3.0.0 || ^4.0.0" }
|
|
22
|
+
},
|
|
23
|
+
defaults: {
|
|
24
|
+
endpoints: { cms: "cmsUrl", report: "reportUrl", poolTrading: "poolTradingUrl" },
|
|
25
|
+
clientId: "clientId",
|
|
26
|
+
storage: "cookie",
|
|
27
|
+
mock: false,
|
|
28
|
+
wsTopics: [],
|
|
29
|
+
wsAutoOpen: true
|
|
30
|
+
},
|
|
31
|
+
setup(options, nuxt) {
|
|
32
|
+
const logger = useLogger("cms-sdk");
|
|
33
|
+
const { resolve } = createResolver(import.meta.url);
|
|
34
|
+
nuxt.options.runtimeConfig.public ??= {};
|
|
35
|
+
nuxt.options.runtimeConfig.public.cmsSdkOptions = options;
|
|
36
|
+
for (const [route, file] of SERVER_HANDLERS) {
|
|
37
|
+
addServerHandler({ route, handler: resolve(file) });
|
|
38
|
+
}
|
|
39
|
+
addPlugin({ src: resolve("runtime/plugin.js") });
|
|
40
|
+
if (options.mock) {
|
|
41
|
+
logger.warn("cms-sdk: mock mode is ON — domain services return fake data.");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export { nuxt as default };
|
|
47
|
+
//# sourceMappingURL=nuxt.js.map
|
package/dist/nuxt.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt.js","sources":["../src/nuxt.ts"],"sourcesContent":["import {\n addPlugin,\n addServerHandler,\n createResolver,\n defineNuxtModule,\n useLogger,\n} from '@nuxt/kit';\nimport type { RequestCasing, ResponseCasing } from './common/constants/http.constant';\nimport type { StorageName } from './common/constants/storage.constant';\n\nexport interface IModuleOptions {\n /**\n * Names of `runtimeConfig.public` keys holding each endpoint URL.\n * Default reads `cmsUrl`, `reportUrl`, `poolTradingUrl`.\n */\n endpoints?: Record<string, string>;\n clientId?: string;\n /** Storage backend name. Default 'cookie'. */\n storage?: StorageName;\n /** Use fake data until the backend is ready. Default false. */\n mock?: boolean;\n timeout?: number;\n retry?: number;\n /** Response casing to request from the backend (`x-response-casing`). Default camel. */\n responseCasing?: ResponseCasing;\n /** Request casing declared to the backend (`x-request-casing`). Default camel. */\n requestCasing?: RequestCasing;\n /**\n * Topics to subscribe to automatically after the WS connection opens.\n * Server-side permissions still apply (FEAT-010 §5.4).\n *\n * Defaults to `[]` (consumer-driven via `useWsStore().subscribe([...])`).\n */\n wsTopics?: string[];\n /**\n * Auto-open the WebSocket on app mount (client-only). Default `true`.\n * Set `false` for consumers that prefer explicit `useWsStore().open()`.\n */\n wsAutoOpen?: boolean;\n}\n\nconst SERVER_HANDLERS: Array<[route: string, file: string]> = [\n ['/api/cms/set-token', 'server/set-token.post.js'],\n ['/api/cms/clear-token', 'server/clear-token.delete.js'],\n ['/api/cms/login', 'server/auth/login.post.js'],\n ['/api/cms/logout', 'server/auth/logout.post.js'],\n ['/api/cms/refresh', 'server/auth/refresh.post.js'],\n ['/api/cms/cbs-start', 'server/auth/cbs-start.post.js'],\n ['/api/cms/cbs-callback', 'server/auth/cbs-callback.post.js'],\n ['/api/cms/idp-login', 'server/auth/idp-login.get.js'],\n ['/api/cms/idp-callback', 'server/auth/idp-callback.get.js'],\n ['/api/cms/idp-link', 'server/auth/idp-link.post.js'],\n ['/api/cms/idp-unlink', 'server/auth/idp-unlink.delete.js'],\n ['/api/cms-sdk/persist', 'server/persist.post.js'],\n];\n\n/**\n * Nuxt module: registers a plugin that builds the CMS SDK from runtime\n * config and provides it as `$cms` / `useNuxtApp().$cms`. Also attaches the\n * SDK to the auth Pinia store and installs persistence.\n *\n * Consumer config:\n * ```ts\n * export default defineNuxtConfig({\n * modules: ['@zeitvu97/cms-sdk/nuxt'],\n * runtimeConfig: { public: { cmsUrl: 'https://...', clientId: 'web' } },\n * cmsSdk: { storage: 'cookie', mock: true },\n * })\n * ```\n */\nexport default defineNuxtModule<IModuleOptions>({\n meta: {\n name: '@zeitvu97/cms-sdk',\n configKey: 'cmsSdk',\n compatibility: { nuxt: '^3.0.0 || ^4.0.0' },\n },\n defaults: {\n endpoints: { cms: 'cmsUrl', report: 'reportUrl', poolTrading: 'poolTradingUrl' },\n clientId: 'clientId',\n storage: 'cookie',\n mock: false,\n wsTopics: [],\n wsAutoOpen: true,\n },\n setup(options, nuxt) {\n const logger = useLogger('cms-sdk');\n const { resolve } = createResolver(import.meta.url);\n\n nuxt.options.runtimeConfig.public ??= {};\n (nuxt.options.runtimeConfig.public as Record<string, unknown>).cmsSdkOptions = options;\n\n for (const [route, file] of SERVER_HANDLERS) {\n addServerHandler({ route, handler: resolve(file) });\n }\n\n addPlugin({ src: resolve('runtime/plugin.js') });\n\n if (options.mock) {\n logger.warn('cms-sdk: mock mode is ON — domain services return fake data.');\n }\n },\n});\n"],"names":[],"mappings":";;AAyCA,MAAM,eAAA,GAAwD;AAAA,EAC5D,CAAC,sBAAsB,0BAA0B,CAAA;AAAA,EACjD,CAAC,wBAAwB,8BAA8B,CAAA;AAAA,EACvD,CAAC,kBAAkB,2BAA2B,CAAA;AAAA,EAC9C,CAAC,mBAAmB,4BAA4B,CAAA;AAAA,EAChD,CAAC,oBAAoB,6BAA6B,CAAA;AAAA,EAClD,CAAC,sBAAsB,+BAA+B,CAAA;AAAA,EACtD,CAAC,yBAAyB,kCAAkC,CAAA;AAAA,EAC5D,CAAC,sBAAsB,8BAA8B,CAAA;AAAA,EACrD,CAAC,yBAAyB,iCAAiC,CAAA;AAAA,EAC3D,CAAC,qBAAqB,8BAA8B,CAAA;AAAA,EACpD,CAAC,uBAAuB,kCAAkC,CAAA;AAAA,EAC1D,CAAC,wBAAwB,wBAAwB;AACnD,CAAA;AAgBA,aAAe,gBAAA,CAAiC;AAAA,EAC9C,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,mBAAA;AAAA,IACN,SAAA,EAAW,QAAA;AAAA,IACX,aAAA,EAAe,EAAE,IAAA,EAAM,kBAAA;AAAmB,GAC5C;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW,EAAE,GAAA,EAAK,UAAU,MAAA,EAAQ,WAAA,EAAa,aAAa,gBAAA,EAAiB;AAAA,IAC/E,QAAA,EAAU,UAAA;AAAA,IACV,OAAA,EAAS,QAAA;AAAA,IACT,IAAA,EAAM,KAAA;AAAA,IACN,UAAU,EAAC;AAAA,IACX,UAAA,EAAY;AAAA,GACd;AAAA,EACA,KAAA,CAAM,SAAS,IAAA,EAAM;AACnB,IAAA,MAAM,MAAA,GAAS,UAAU,SAAS,CAAA;AAClC,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,cAAA,CAAe,YAAY,GAAG,CAAA;AAElD,IAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,KAAW,EAAC;AACvC,IAAC,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAmC,aAAA,GAAgB,OAAA;AAE/E,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,CAAA,IAAK,eAAA,EAAiB;AAC3C,MAAA,gBAAA,CAAiB,EAAE,KAAA,EAAO,OAAA,EAAS,OAAA,CAAQ,IAAI,GAAG,CAAA;AAAA,IACpD;AAEA,IAAA,SAAA,CAAU,EAAE,GAAA,EAAK,OAAA,CAAQ,mBAAmB,GAAG,CAAA;AAE/C,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,MAAA,CAAO,KAAK,8DAA8D,CAAA;AAAA,IAC5E;AAAA,EACF;AACF,CAAC,CAAA;;;;"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { createCmsSDK, createPersistPlugin, TOKEN_STORAGE_KEY, useAuthStore, useContentStore, useHistoryStore, useKalshiStore, useRulesStore, useExecutionsStore, useSettingsStore, useLlmStore, useLlmProvidersStore, useGovStore, usePeopleStore, useWsStore } from '@zeitvu97/cms-sdk';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { watch } from 'vue';
|
|
4
|
+
import { defineNuxtPlugin, useRuntimeConfig, useCookie } from '#app';
|
|
5
|
+
|
|
6
|
+
function buildOpts(httpOnly) {
|
|
7
|
+
return httpOnly ? { httpOnly: true, secure: true, sameSite: "lax", path: "/" } : { secure: true, sameSite: "lax", path: "/" };
|
|
8
|
+
}
|
|
9
|
+
function createCookieStorage(useCookie) {
|
|
10
|
+
return {
|
|
11
|
+
getItem(key) {
|
|
12
|
+
return useCookie(key).value;
|
|
13
|
+
},
|
|
14
|
+
setItem(key, value, opts) {
|
|
15
|
+
useCookie(key, buildOpts(!!opts?.httpOnly)).value = value;
|
|
16
|
+
},
|
|
17
|
+
removeItem(key, opts) {
|
|
18
|
+
useCookie(key, buildOpts(!!opts?.httpOnly)).value = null;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const TOKEN_COOKIE_OPTIONS = {
|
|
24
|
+
httpOnly: true,
|
|
25
|
+
secure: true,
|
|
26
|
+
sameSite: "lax",
|
|
27
|
+
path: "/",
|
|
28
|
+
maxAge: 60 * 60 * 24 * 30
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const STORE_ATTACHMENTS = [
|
|
32
|
+
{ name: "auth", get: useAuthStore },
|
|
33
|
+
{ name: "content", get: useContentStore },
|
|
34
|
+
{ name: "history", get: useHistoryStore },
|
|
35
|
+
{ name: "kalshi", get: useKalshiStore },
|
|
36
|
+
{ name: "rules", get: useRulesStore },
|
|
37
|
+
{ name: "executions", get: useExecutionsStore },
|
|
38
|
+
{ name: "settings", get: useSettingsStore },
|
|
39
|
+
{ name: "llm", get: useLlmStore },
|
|
40
|
+
{ name: "llm-providers", get: useLlmProvidersStore },
|
|
41
|
+
{ name: "gov", get: useGovStore },
|
|
42
|
+
{ name: "people", get: usePeopleStore },
|
|
43
|
+
{ name: "ws", get: useWsStore }
|
|
44
|
+
];
|
|
45
|
+
function attachStores(pinia, sdk) {
|
|
46
|
+
let authStore;
|
|
47
|
+
let wsStore;
|
|
48
|
+
for (const { name, get } of STORE_ATTACHMENTS) {
|
|
49
|
+
try {
|
|
50
|
+
const store = get(pinia);
|
|
51
|
+
store?.setSdk?.(sdk);
|
|
52
|
+
if (name === "auth") authStore = store;
|
|
53
|
+
if (name === "ws") wsStore = store;
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.warn(`[cms-sdk] could not attach SDK to ${name} store:`, e);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { authStore, wsStore };
|
|
59
|
+
}
|
|
60
|
+
const plugin = defineNuxtPlugin(async (nuxtApp) => {
|
|
61
|
+
const config = useRuntimeConfig();
|
|
62
|
+
const opts = config.public?.cmsSdkOptions ?? {};
|
|
63
|
+
const pub = config.public ?? {};
|
|
64
|
+
const endpoints = {};
|
|
65
|
+
for (const [name, runtimeKey] of Object.entries(
|
|
66
|
+
opts.endpoints ?? { cms: "cmsUrl" }
|
|
67
|
+
)) {
|
|
68
|
+
const url = pub[runtimeKey];
|
|
69
|
+
if (url) endpoints[name] = url;
|
|
70
|
+
}
|
|
71
|
+
const wsUrl = pub.wsUrl || pub.cmsWsUrl;
|
|
72
|
+
if (wsUrl) endpoints.ws = wsUrl;
|
|
73
|
+
let sdkInstance = null;
|
|
74
|
+
const onToken = async (token) => {
|
|
75
|
+
if (!sdkInstance) return;
|
|
76
|
+
if (token) sdkInstance.tokenManager.set(token);
|
|
77
|
+
else sdkInstance.tokenManager.clear();
|
|
78
|
+
if (import.meta.server) {
|
|
79
|
+
const { setCookie, deleteCookie } = await import('h3');
|
|
80
|
+
const event = nuxtApp.ssrContext?.event;
|
|
81
|
+
if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);
|
|
82
|
+
else deleteCookie(event, TOKEN_STORAGE_KEY, { path: TOKEN_COOKIE_OPTIONS.path });
|
|
83
|
+
} else if (token) {
|
|
84
|
+
await $fetch("/api/cms/set-token", { method: "POST", body: { token } });
|
|
85
|
+
} else {
|
|
86
|
+
await $fetch("/api/cms/clear-token", { method: "DELETE" });
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const authRoute = $fetch.create({ baseURL: "/api/cms" });
|
|
90
|
+
const refresh = async () => {
|
|
91
|
+
try {
|
|
92
|
+
const res = await $fetch("/api/cms/refresh", { method: "POST" });
|
|
93
|
+
return res.token ?? null;
|
|
94
|
+
} catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const sdk = createCmsSDK({
|
|
99
|
+
endpoints,
|
|
100
|
+
clientId: opts.clientId ? pub[opts.clientId] : void 0,
|
|
101
|
+
credentials: { storage: "memory" },
|
|
102
|
+
mock: !!opts.mock,
|
|
103
|
+
timeout: opts.timeout,
|
|
104
|
+
retry: opts.retry,
|
|
105
|
+
onToken,
|
|
106
|
+
refresh,
|
|
107
|
+
responseCasing: opts.responseCasing,
|
|
108
|
+
requestCasing: opts.requestCasing,
|
|
109
|
+
authRoute
|
|
110
|
+
});
|
|
111
|
+
sdkInstance = sdk;
|
|
112
|
+
const pinia = nuxtApp.$pinia;
|
|
113
|
+
if (!pinia) {
|
|
114
|
+
console.warn("[cms-sdk] Pinia is not available — register @pinia/nuxt before this module.");
|
|
115
|
+
return { provide: { cms: sdk, ws: sdk.ws } };
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
pinia.use(
|
|
119
|
+
createPersistPlugin({
|
|
120
|
+
storage: createCookieStorage(useCookie),
|
|
121
|
+
httpEndpoint: "/api/cms-sdk/persist",
|
|
122
|
+
ssr: import.meta.server
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.warn("[cms-sdk] persistence plugin install failed:", e);
|
|
127
|
+
}
|
|
128
|
+
const { authStore, wsStore } = attachStores(pinia, sdk);
|
|
129
|
+
try {
|
|
130
|
+
if (import.meta.server) {
|
|
131
|
+
const token = useCookie(TOKEN_STORAGE_KEY).value;
|
|
132
|
+
if (token) sdk.tokenManager.set(token);
|
|
133
|
+
} else if (authStore?.accessToken) {
|
|
134
|
+
sdk.tokenManager.set(authStore.accessToken);
|
|
135
|
+
}
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.warn("[cms-sdk] could not seed token manager:", e);
|
|
138
|
+
}
|
|
139
|
+
if (!import.meta.server && sdk.ws && wsStore) {
|
|
140
|
+
try {
|
|
141
|
+
const topics = opts.wsTopics ?? [];
|
|
142
|
+
const subscribeDeclarativeTopics = () => {
|
|
143
|
+
if (topics.length) wsStore.subscribe(topics);
|
|
144
|
+
};
|
|
145
|
+
if (opts.wsAutoOpen !== false) wsStore.open();
|
|
146
|
+
subscribeDeclarativeTopics();
|
|
147
|
+
const isAnonSafeTopic = (t) => t.startsWith("symbol:") || t.startsWith("mt5:events:") && t.endsWith(":tick");
|
|
148
|
+
const selectiveUnsubscribeNonAnon = () => {
|
|
149
|
+
const toRemove = [...wsStore.subscribed].filter((t) => !isAnonSafeTopic(t));
|
|
150
|
+
if (toRemove.length) wsStore.unsubscribe(toRemove);
|
|
151
|
+
};
|
|
152
|
+
if (authStore) {
|
|
153
|
+
let lastSeenUserId = authStore.authUser?.id ?? null;
|
|
154
|
+
watch(
|
|
155
|
+
() => authStore.loginEpoch,
|
|
156
|
+
() => {
|
|
157
|
+
const currentUserId = authStore.authUser?.id ?? null;
|
|
158
|
+
if (currentUserId !== lastSeenUserId) {
|
|
159
|
+
selectiveUnsubscribeNonAnon();
|
|
160
|
+
lastSeenUserId = currentUserId;
|
|
161
|
+
}
|
|
162
|
+
wsStore.reopen();
|
|
163
|
+
subscribeDeclarativeTopics();
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
watch(
|
|
167
|
+
() => authStore.isLoggedIn,
|
|
168
|
+
(loggedIn, previous) => {
|
|
169
|
+
if (loggedIn) {
|
|
170
|
+
wsStore.reopen();
|
|
171
|
+
subscribeDeclarativeTopics();
|
|
172
|
+
} else if (previous === true) {
|
|
173
|
+
selectiveUnsubscribeNonAnon();
|
|
174
|
+
wsStore.close("user-logout");
|
|
175
|
+
wsStore.open();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.warn("[cms-sdk] WS open/subscribe failed:", e);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return { provide: { cms: sdk, ws: sdk.ws } };
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
export { plugin as default };
|
|
188
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../src/runtime/cookie-storage.ts","../../src/runtime/token-cookie-options.ts","../../src/runtime/plugin.ts"],"sourcesContent":["type UseCookieFn = <T>(key: string, opts?: Record<string, unknown>) => { value: T | null };\n\nfunction buildOpts(httpOnly: boolean) {\n return httpOnly\n ? { httpOnly: true, secure: true, sameSite: 'lax', path: '/' }\n : { secure: true, sameSite: 'lax', path: '/' };\n}\n\nexport function createCookieStorage(useCookie: UseCookieFn) {\n return {\n getItem(key: string): string | null {\n return useCookie<string>(key).value;\n },\n setItem(key: string, value: string, opts?: { httpOnly?: boolean }) {\n useCookie(key, buildOpts(!!opts?.httpOnly)).value = value;\n },\n removeItem(key: string, opts?: { httpOnly?: boolean }) {\n useCookie<null>(key, buildOpts(!!opts?.httpOnly)).value = null;\n },\n };\n}\n","export const TOKEN_COOKIE_OPTIONS = {\n httpOnly: true,\n secure: true,\n sameSite: 'lax' as const,\n path: '/',\n maxAge: 60 * 60 * 24 * 30,\n};\n","import {\n createCmsSDK,\n createPersistPlugin,\n TOKEN_STORAGE_KEY,\n useAuthStore,\n useContentStore,\n useExecutionsStore,\n useGovStore,\n useHistoryStore,\n useKalshiStore,\n useLlmProvidersStore,\n useLlmStore,\n usePeopleStore,\n useRulesStore,\n useSettingsStore,\n useWsStore,\n} from '@zeitvu97/cms-sdk';\nimport { $fetch } from 'ofetch';\nimport { watch } from 'vue';\nimport { defineNuxtPlugin, useCookie, useRuntimeConfig } from '#app';\n\nimport { createCookieStorage } from './cookie-storage';\nimport { TOKEN_COOKIE_OPTIONS } from './token-cookie-options';\n\nconst STORE_ATTACHMENTS = [\n { name: 'auth', get: useAuthStore },\n { name: 'content', get: useContentStore },\n { name: 'history', get: useHistoryStore },\n { name: 'kalshi', get: useKalshiStore },\n { name: 'rules', get: useRulesStore },\n { name: 'executions', get: useExecutionsStore },\n { name: 'settings', get: useSettingsStore },\n { name: 'llm', get: useLlmStore },\n { name: 'llm-providers', get: useLlmProvidersStore },\n { name: 'gov', get: useGovStore },\n { name: 'people', get: usePeopleStore },\n { name: 'ws', get: useWsStore },\n] as const;\n\nfunction attachStores(pinia: any, sdk: any): { authStore: any; wsStore: any } {\n let authStore: any;\n let wsStore: any;\n\n for (const { name, get } of STORE_ATTACHMENTS) {\n try {\n const store = get(pinia);\n store?.setSdk?.(sdk);\n if (name === 'auth') authStore = store;\n if (name === 'ws') wsStore = store;\n } catch (e) {\n console.warn(`[cms-sdk] could not attach SDK to ${name} store:`, e);\n }\n }\n\n return { authStore, wsStore };\n}\n\nexport default defineNuxtPlugin(async (nuxtApp: any) => {\n const config = useRuntimeConfig();\n const opts = config.public?.cmsSdkOptions ?? {};\n const pub = config.public ?? {};\n\n // --- Resolve endpoints from runtimeConfig keys ---\n const endpoints: Record<string, string> = {};\n for (const [name, runtimeKey] of Object.entries(\n (opts.endpoints as Record<string, string>) ?? { cms: 'cmsUrl' }\n )) {\n const url = pub[runtimeKey as string];\n if (url) endpoints[name] = url;\n }\n\n const wsUrl = pub.wsUrl || pub.cmsWsUrl;\n if (wsUrl) endpoints.ws = wsUrl;\n\n // --- Token lifecycle (httpOnly cookie set/clear via /api/cms/* routes) ---\n let sdkInstance: any = null;\n\n const onToken = async (token: string | null) => {\n if (!sdkInstance) return;\n if (token) sdkInstance.tokenManager.set(token);\n else sdkInstance.tokenManager.clear();\n\n if (import.meta.server) {\n const { setCookie, deleteCookie } = await import('h3');\n const event = nuxtApp.ssrContext?.event;\n if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);\n else deleteCookie(event, TOKEN_STORAGE_KEY, { path: TOKEN_COOKIE_OPTIONS.path });\n } else if (token) {\n await $fetch('/api/cms/set-token', { method: 'POST', body: { token } });\n } else {\n await $fetch('/api/cms/clear-token', { method: 'DELETE' });\n }\n };\n\n const authRoute = $fetch.create({ baseURL: '/api/cms' });\n\n const refresh = async () => {\n try {\n const res = (await $fetch('/api/cms/refresh', { method: 'POST' })) as { token?: string };\n return res.token ?? null;\n } catch {\n return null;\n }\n };\n\n // --- Create SDK instance ---\n const sdk = createCmsSDK({\n endpoints: endpoints as any,\n clientId: opts.clientId ? pub[opts.clientId] : undefined,\n credentials: { storage: 'memory' },\n mock: !!opts.mock,\n timeout: opts.timeout,\n retry: opts.retry,\n onToken,\n refresh,\n responseCasing: opts.responseCasing,\n requestCasing: opts.requestCasing,\n authRoute,\n });\n sdkInstance = sdk;\n\n // --- Pinia wiring ---\n const pinia = nuxtApp.$pinia;\n if (!pinia) {\n console.warn('[cms-sdk] Pinia is not available — register @pinia/nuxt before this module.');\n return { provide: { cms: sdk, ws: sdk.ws } };\n }\n\n try {\n pinia.use(\n createPersistPlugin({\n storage: createCookieStorage(useCookie),\n httpEndpoint: '/api/cms-sdk/persist',\n ssr: import.meta.server,\n })\n );\n } catch (e) {\n console.warn('[cms-sdk] persistence plugin install failed:', e);\n }\n\n const { authStore, wsStore } = attachStores(pinia, sdk);\n\n // --- Seed token manager ---\n try {\n if (import.meta.server) {\n const token = useCookie(TOKEN_STORAGE_KEY).value;\n if (token) sdk.tokenManager.set(token);\n } else if (authStore?.accessToken) {\n sdk.tokenManager.set(authStore.accessToken);\n }\n } catch (e) {\n console.warn('[cms-sdk] could not seed token manager:', e);\n }\n\n // --- FEAT-010: open WS + auto-subscribe on the client ---\n if (!import.meta.server && sdk.ws && wsStore) {\n try {\n const topics = (opts.wsTopics as string[] | undefined) ?? [];\n const subscribeDeclarativeTopics = (): void => {\n if (topics.length) wsStore.subscribe(topics);\n };\n if (opts.wsAutoOpen !== false) wsStore.open();\n subscribeDeclarativeTopics();\n\n // Re-login flow: the user authenticates AFTER the app has booted\n // (the WS was opened with no token, so the server dropped it for\n // `auth_timeout`). We watch `authStore.isLoggedIn` and force a fresh\n // handshake on every false → true transition so the new token is\n // sent and previously-subscribed topics are replayed automatically\n // by the WS client's `flushSubscriptions` on `auth_ok`. On logout\n // (true → false) we close cleanly so the old session is dropped\n // server-side instead of staying authenticated until `auth_expired`.\n // Anonymous-safe topics survive a logout → anonymous reconnect: only\n // `symbol:<server>:<SYMBOL>` and `mt5:events:<server>:tick` are admitted\n // on an anonymous connection (ws-guide §11.3). Everything else\n // (account/order/position/user-scoped) is dropped before the close so it\n // is not replayed onto the anonymous socket as `sub_error` spam or leaked\n // across users.\n const isAnonSafeTopic = (t: string): boolean =>\n t.startsWith('symbol:') || (t.startsWith('mt5:events:') && t.endsWith(':tick'));\n const selectiveUnsubscribeNonAnon = (): void => {\n const toRemove = [...wsStore.subscribed].filter((t) => !isAnonSafeTopic(t));\n if (toRemove.length) wsStore.unsubscribe(toRemove);\n };\n\n if (authStore) {\n // Tracks the authenticated user id so a silent cross-user re-login\n // (e.g. super-app injecting a different user's token without a logout)\n // can tear down the previous user's non-anonymous topics.\n let lastSeenUserId: string | number | null | undefined = authStore.authUser?.id ?? null;\n\n // Re-login / token-rotation while ALREADY authenticated: the\n // `isLoggedIn` boolean does not transition here, so without this the\n // socket would keep the stale token until the server pushed\n // `auth_expired`. `login()` / `loginWithTokenAndUser()` only bump the\n // epoch when the user was already logged in (the initial login is\n // covered by the transition watcher below), and `refreshToken()` always\n // bumps it — so this watcher fires exactly once per explicit\n // re-handshake and never duplicates the transition watcher.\n watch(\n () => authStore.loginEpoch,\n () => {\n const currentUserId = authStore.authUser?.id ?? null;\n if (currentUserId !== lastSeenUserId) {\n selectiveUnsubscribeNonAnon();\n lastSeenUserId = currentUserId;\n }\n wsStore.reopen();\n subscribeDeclarativeTopics();\n }\n );\n watch(\n () => authStore.isLoggedIn,\n (loggedIn, previous) => {\n if (loggedIn) {\n wsStore.reopen();\n subscribeDeclarativeTopics();\n } else if (previous === true) {\n // Drop user-scoped topics (keep anon-safe market data), then\n // establish a fresh anonymous connection so live symbol ticks\n // keep streaming after logout.\n selectiveUnsubscribeNonAnon();\n wsStore.close('user-logout');\n wsStore.open();\n }\n }\n );\n }\n } catch (e) {\n console.warn('[cms-sdk] WS open/subscribe failed:', e);\n }\n }\n\n return { provide: { cms: sdk, ws: sdk.ws } };\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineEventHandler, createError, readBody, parseCookies, getRequestHeader, setCookie } from 'h3';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { b as HTTP_HEADER, c as AUTH_ENDPOINT } from '../../chunks/auth.constant-DO7ZmsKg.js';
|
|
4
|
+
import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-48T7q0V3.js';
|
|
5
|
+
import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant--64BDSPW.js';
|
|
6
|
+
|
|
7
|
+
const cbsCallback_post = defineEventHandler(async (event) => {
|
|
8
|
+
const { cmsUrl, clientId } = readSdkConfig(event);
|
|
9
|
+
if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
|
|
10
|
+
const body = await readBody(event);
|
|
11
|
+
const cookies = parseCookies(event);
|
|
12
|
+
const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || "";
|
|
13
|
+
try {
|
|
14
|
+
const response = await $fetch.raw(AUTH_ENDPOINT.CBS_CALLBACK, {
|
|
15
|
+
baseURL: cmsUrl,
|
|
16
|
+
method: "POST",
|
|
17
|
+
body,
|
|
18
|
+
headers: {
|
|
19
|
+
[HTTP_HEADER.CLIENT_ID]: clientId || "",
|
|
20
|
+
[HTTP_HEADER.DEVICE_ID]: cookies.device_id || "",
|
|
21
|
+
[HTTP_HEADER.DEVICE_IP]: cookies.device_ip || "",
|
|
22
|
+
[HTTP_HEADER.USER_AGENT]: userAgent
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const data = response._data ?? {};
|
|
26
|
+
const token = data.accessToken ?? data.access_token ?? "";
|
|
27
|
+
const refreshToken = data.refreshToken ?? data.refresh_token ?? "";
|
|
28
|
+
if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);
|
|
29
|
+
if (refreshToken)
|
|
30
|
+
setCookie(event, REFRESH_TOKEN_STORAGE_KEY, refreshToken, TOKEN_COOKIE_OPTIONS);
|
|
31
|
+
return { ...data, token };
|
|
32
|
+
} catch (err) {
|
|
33
|
+
throw createError({
|
|
34
|
+
statusCode: err?.response?.status || err?.statusCode || 500,
|
|
35
|
+
message: err?.data?.error || err?.data?.message || err?.message || "CBS callback failed",
|
|
36
|
+
data: err?.data
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export { cbsCallback_post as default };
|
|
42
|
+
//# sourceMappingURL=cbs-callback.post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbs-callback.post.js","sources":["../../../src/server/auth/cbs-callback.post.ts"],"sourcesContent":["import {\n defineEventHandler,\n readBody,\n parseCookies,\n getRequestHeader,\n setCookie,\n createError,\n} from 'h3';\nimport { $fetch } from 'ofetch';\nimport { AUTH_ENDPOINT } from '../../common/constants/auth.constant';\nimport { HTTP_HEADER } from '../../common/constants/http.constant';\nimport {\n readSdkConfig,\n REFRESH_TOKEN_STORAGE_KEY,\n TOKEN_COOKIE_OPTIONS,\n TOKEN_STORAGE_KEY,\n} from './_shared';\n\n/**\n * Thin auth proxy: POST /api/cms/cbs-callback → backend POST /api/v1/auth/oauth/cbs/callback.\n *\n * Completes a \"Login with CBS\" attempt. Forwards `{ code, state, stateKey }`;\n * the backend verifies PKCE/state, exchanges the code for a CBS JWT, JIT-links\n * the CBS identity to a CMS user, and mints a CMS session JWT (RS256) + refresh\n * token. This route stores both as httpOnly cookies and returns the body\n * augmented with a `token` field so the client can mirror the access token in\n * memory (the httpOnly cookie is the durable copy used for SSR).\n */\nexport default defineEventHandler(async (event) => {\n const { cmsUrl, clientId } = readSdkConfig(event);\n if (!cmsUrl) throw createError({ statusCode: 500, message: 'CMS URL not configured' });\n\n const body = await readBody(event);\n const cookies = parseCookies(event);\n const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || '';\n\n try {\n const response = await $fetch.raw(AUTH_ENDPOINT.CBS_CALLBACK, {\n baseURL: cmsUrl,\n method: 'POST',\n body,\n headers: {\n [HTTP_HEADER.CLIENT_ID]: clientId || '',\n [HTTP_HEADER.DEVICE_ID]: cookies.device_id || '',\n [HTTP_HEADER.DEVICE_IP]: cookies.device_ip || '',\n [HTTP_HEADER.USER_AGENT]: userAgent,\n },\n });\n const data = (response._data ?? {}) as Record<string, unknown>;\n const token =\n (data.accessToken as string | undefined) ?? (data.access_token as string | undefined) ?? '';\n const refreshToken =\n (data.refreshToken as string | undefined) ?? (data.refresh_token as string | undefined) ?? '';\n if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);\n if (refreshToken)\n setCookie(event, REFRESH_TOKEN_STORAGE_KEY, refreshToken, TOKEN_COOKIE_OPTIONS);\n return { ...data, token };\n } catch (err: any) {\n throw createError({\n statusCode: err?.response?.status || err?.statusCode || 500,\n message: err?.data?.error || err?.data?.message || err?.message || 'CBS callback failed',\n data: err?.data,\n });\n }\n});\n"],"names":[],"mappings":";;;;;;AA4BA,yBAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAS,GAAI,cAAc,KAAK,CAAA;AAChD,EAAA,IAAI,CAAC,QAAQ,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,wBAAA,EAA0B,CAAA;AAErF,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAK,CAAA;AACjC,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,KAAA,EAAO,WAAA,CAAY,UAAU,CAAA,IAAK,EAAA;AAErE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,GAAA,CAAI,cAAc,YAAA,EAAc;AAAA,MAC5D,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,CAAC,WAAA,CAAY,SAAS,GAAG,QAAA,IAAY,EAAA;AAAA,QACrC,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,UAAU,GAAG;AAAA;AAC5B,KACD,CAAA;AACD,IAAA,MAAM,IAAA,GAAQ,QAAA,CAAS,KAAA,IAAS,EAAC;AACjC,IAAA,MAAM,KAAA,GACH,IAAA,CAAK,WAAA,IAAuC,IAAA,CAAK,YAAA,IAAuC,EAAA;AAC3F,IAAA,MAAM,YAAA,GACH,IAAA,CAAK,YAAA,IAAwC,IAAA,CAAK,aAAA,IAAwC,EAAA;AAC7F,IAAA,IAAI,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,iBAAA,EAAmB,OAAO,oBAAoB,CAAA;AAC1E,IAAA,IAAI,YAAA;AACF,MAAA,SAAA,CAAU,KAAA,EAAO,yBAAA,EAA2B,YAAA,EAAc,oBAAoB,CAAA;AAChF,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,KAAA,EAAM;AAAA,EAC1B,SAAS,GAAA,EAAU;AACjB,IAAA,MAAM,WAAA,CAAY;AAAA,MAChB,UAAA,EAAY,GAAA,EAAK,QAAA,EAAU,MAAA,IAAU,KAAK,UAAA,IAAc,GAAA;AAAA,MACxD,OAAA,EAAS,KAAK,IAAA,EAAM,KAAA,IAAS,KAAK,IAAA,EAAM,OAAA,IAAW,KAAK,OAAA,IAAW,qBAAA;AAAA,MACnE,MAAM,GAAA,EAAK;AAAA,KACZ,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { defineEventHandler, createError, parseCookies, getRequestHeader } from 'h3';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { b as HTTP_HEADER, c as AUTH_ENDPOINT } from '../../chunks/auth.constant-DO7ZmsKg.js';
|
|
4
|
+
import { r as readSdkConfig } from '../../chunks/_shared-48T7q0V3.js';
|
|
5
|
+
|
|
6
|
+
const cbsStart_post = defineEventHandler(async (event) => {
|
|
7
|
+
const { cmsUrl, clientId } = readSdkConfig(event);
|
|
8
|
+
if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
|
|
9
|
+
const cookies = parseCookies(event);
|
|
10
|
+
const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || "";
|
|
11
|
+
try {
|
|
12
|
+
const data = await $fetch(AUTH_ENDPOINT.CBS_START, {
|
|
13
|
+
baseURL: cmsUrl,
|
|
14
|
+
method: "POST",
|
|
15
|
+
body: {},
|
|
16
|
+
headers: {
|
|
17
|
+
[HTTP_HEADER.CLIENT_ID]: clientId || "",
|
|
18
|
+
[HTTP_HEADER.DEVICE_ID]: cookies.device_id || "",
|
|
19
|
+
[HTTP_HEADER.DEVICE_IP]: cookies.device_ip || "",
|
|
20
|
+
[HTTP_HEADER.USER_AGENT]: userAgent
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return data;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
throw createError({
|
|
26
|
+
statusCode: err?.response?.status || err?.statusCode || 500,
|
|
27
|
+
message: err?.data?.error || err?.data?.message || err?.message || "CBS start failed",
|
|
28
|
+
data: err?.data
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export { cbsStart_post as default };
|
|
34
|
+
//# sourceMappingURL=cbs-start.post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbs-start.post.js","sources":["../../../src/server/auth/cbs-start.post.ts"],"sourcesContent":["import { defineEventHandler, parseCookies, getRequestHeader, createError } from 'h3';\nimport { $fetch } from 'ofetch';\nimport { AUTH_ENDPOINT } from '../../common/constants/auth.constant';\nimport { HTTP_HEADER } from '../../common/constants/http.constant';\nimport { readSdkConfig } from './_shared';\n\n/**\n * Thin auth proxy: POST /api/cms/cbs-start → backend POST /api/v1/auth/oauth/cbs/start.\n *\n * Initialises a \"Login with CBS\" attempt. The backend generates the PKCE\n * verifier + state (kept server-side, never exposed to the browser) and returns\n * `{ authorizeUrl, stateKey, redirectTarget }`. No cookie is set here — the CMS\n * session JWT is only minted on `/cbs-callback`.\n *\n * Used by the silent-login iframe handshake: the webtrade iframe calls this to\n * obtain the CBS `authorizeUrl` it hands to the super-app parent (which opens\n * the top-level popup that carries the CBS session cookie).\n */\nexport default defineEventHandler(async (event) => {\n const { cmsUrl, clientId } = readSdkConfig(event);\n if (!cmsUrl) throw createError({ statusCode: 500, message: 'CMS URL not configured' });\n\n const cookies = parseCookies(event);\n const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || '';\n\n try {\n const data = (await $fetch(AUTH_ENDPOINT.CBS_START, {\n baseURL: cmsUrl,\n method: 'POST',\n body: {},\n headers: {\n [HTTP_HEADER.CLIENT_ID]: clientId || '',\n [HTTP_HEADER.DEVICE_ID]: cookies.device_id || '',\n [HTTP_HEADER.DEVICE_IP]: cookies.device_ip || '',\n [HTTP_HEADER.USER_AGENT]: userAgent,\n },\n })) as Record<string, unknown>;\n return data;\n } catch (err: any) {\n throw createError({\n statusCode: err?.response?.status || err?.statusCode || 500,\n message: err?.data?.error || err?.data?.message || err?.message || 'CBS start failed',\n data: err?.data,\n });\n }\n});\n"],"names":[],"mappings":";;;;;AAkBA,sBAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAS,GAAI,cAAc,KAAK,CAAA;AAChD,EAAA,IAAI,CAAC,QAAQ,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,wBAAA,EAA0B,CAAA;AAErF,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,KAAA,EAAO,WAAA,CAAY,UAAU,CAAA,IAAK,EAAA;AAErE,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAQ,MAAM,MAAA,CAAO,aAAA,CAAc,SAAA,EAAW;AAAA,MAClD,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,MAAA;AAAA,MACR,MAAM,EAAC;AAAA,MACP,OAAA,EAAS;AAAA,QACP,CAAC,WAAA,CAAY,SAAS,GAAG,QAAA,IAAY,EAAA;AAAA,QACrC,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,UAAU,GAAG;AAAA;AAC5B,KACD,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAU;AACjB,IAAA,MAAM,WAAA,CAAY;AAAA,MAChB,UAAA,EAAY,GAAA,EAAK,QAAA,EAAU,MAAA,IAAU,KAAK,UAAA,IAAc,GAAA;AAAA,MACxD,OAAA,EAAS,KAAK,IAAA,EAAM,KAAA,IAAS,KAAK,IAAA,EAAM,OAAA,IAAW,KAAK,OAAA,IAAW,kBAAA;AAAA,MACnE,MAAM,GAAA,EAAK;AAAA,KACZ,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineEventHandler, createError, getQuery, parseCookies, getRequestHeader, setCookie } from 'h3';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { b as HTTP_HEADER, c as AUTH_ENDPOINT } from '../../chunks/auth.constant-DO7ZmsKg.js';
|
|
4
|
+
import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-48T7q0V3.js';
|
|
5
|
+
import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant--64BDSPW.js';
|
|
6
|
+
|
|
7
|
+
const idpCallback_get = defineEventHandler(async (event) => {
|
|
8
|
+
const { cmsUrl, clientId } = readSdkConfig(event);
|
|
9
|
+
if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
|
|
10
|
+
const query = getQuery(event);
|
|
11
|
+
const provider = (query.provider ?? "").trim();
|
|
12
|
+
const code = (query.code ?? "").trim();
|
|
13
|
+
const state = (query.state ?? "").trim();
|
|
14
|
+
const redirectUri = (query.redirect_uri ?? "").trim();
|
|
15
|
+
if (!provider) throw createError({ statusCode: 400, message: "provider is required" });
|
|
16
|
+
if (!code || !state || !redirectUri) {
|
|
17
|
+
throw createError({ statusCode: 400, message: "code, state and redirect_uri are required" });
|
|
18
|
+
}
|
|
19
|
+
const cookies = parseCookies(event);
|
|
20
|
+
const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || "";
|
|
21
|
+
try {
|
|
22
|
+
const data = await $fetch(AUTH_ENDPOINT.idpCallback(provider), {
|
|
23
|
+
baseURL: cmsUrl,
|
|
24
|
+
method: "GET",
|
|
25
|
+
query: { code, state, redirect_uri: redirectUri },
|
|
26
|
+
headers: {
|
|
27
|
+
[HTTP_HEADER.CLIENT_ID]: clientId || "",
|
|
28
|
+
[HTTP_HEADER.DEVICE_ID]: cookies.device_id || "",
|
|
29
|
+
[HTTP_HEADER.DEVICE_IP]: cookies.device_ip || "",
|
|
30
|
+
[HTTP_HEADER.USER_AGENT]: userAgent
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const token = data.accessToken ?? data.access_token ?? "";
|
|
34
|
+
const refreshToken = data.refreshToken ?? data.refresh_token ?? "";
|
|
35
|
+
if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);
|
|
36
|
+
if (refreshToken)
|
|
37
|
+
setCookie(event, REFRESH_TOKEN_STORAGE_KEY, refreshToken, TOKEN_COOKIE_OPTIONS);
|
|
38
|
+
return { ...data, token };
|
|
39
|
+
} catch (err) {
|
|
40
|
+
const beData = err?.data ?? {};
|
|
41
|
+
const detail = beData.detail ?? {};
|
|
42
|
+
const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;
|
|
43
|
+
throw createError({
|
|
44
|
+
statusCode: err?.response?.status || err?.statusCode || 500,
|
|
45
|
+
message: message || "IdP callback failed",
|
|
46
|
+
data: beData
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export { idpCallback_get as default };
|
|
52
|
+
//# sourceMappingURL=idp-callback.get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idp-callback.get.js","sources":["../../../src/server/auth/idp-callback.get.ts"],"sourcesContent":["import {\n defineEventHandler,\n parseCookies,\n getQuery,\n getRequestHeader,\n setCookie,\n createError,\n} from 'h3';\nimport { $fetch } from 'ofetch';\nimport { AUTH_ENDPOINT } from '../../common/constants/auth.constant';\nimport { HTTP_HEADER } from '../../common/constants/http.constant';\nimport {\n readSdkConfig,\n REFRESH_TOKEN_STORAGE_KEY,\n TOKEN_COOKIE_OPTIONS,\n TOKEN_STORAGE_KEY,\n} from './_shared';\n\n/**\n * Thin auth proxy: GET /api/cms/idp-callback → backend GET /api/auth/{provider}/callback.\n *\n * Completes an IdP SSO login: the backend verifies the one-use state, exchanges\n * the authorization code with the provider, and mints a CMS JWT (resolved via\n * JWKS — usable as a normal Bearer credential) + refresh token. This route\n * stores both as httpOnly cookies and returns the body augmented with a\n * `token` field so the client can mirror the access token in memory.\n */\nexport default defineEventHandler(async (event) => {\n const { cmsUrl, clientId } = readSdkConfig(event);\n if (!cmsUrl) throw createError({ statusCode: 500, message: 'CMS URL not configured' });\n\n const query = getQuery(event) as Record<string, string>;\n const provider = (query.provider ?? '').trim();\n const code = (query.code ?? '').trim();\n const state = (query.state ?? '').trim();\n const redirectUri = (query.redirect_uri ?? '').trim();\n if (!provider) throw createError({ statusCode: 400, message: 'provider is required' });\n if (!code || !state || !redirectUri) {\n throw createError({ statusCode: 400, message: 'code, state and redirect_uri are required' });\n }\n\n const cookies = parseCookies(event);\n const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || '';\n\n try {\n const data = (await $fetch(AUTH_ENDPOINT.idpCallback(provider), {\n baseURL: cmsUrl,\n method: 'GET',\n query: { code, state, redirect_uri: redirectUri },\n headers: {\n [HTTP_HEADER.CLIENT_ID]: clientId || '',\n [HTTP_HEADER.DEVICE_ID]: cookies.device_id || '',\n [HTTP_HEADER.DEVICE_IP]: cookies.device_ip || '',\n [HTTP_HEADER.USER_AGENT]: userAgent,\n },\n })) as Record<string, unknown>;\n const token =\n (data.accessToken as string | undefined) ?? (data.access_token as string | undefined) ?? '';\n const refreshToken =\n (data.refreshToken as string | undefined) ?? (data.refresh_token as string | undefined) ?? '';\n if (token) setCookie(event, TOKEN_STORAGE_KEY, token, TOKEN_COOKIE_OPTIONS);\n if (refreshToken)\n setCookie(event, REFRESH_TOKEN_STORAGE_KEY, refreshToken, TOKEN_COOKIE_OPTIONS);\n return { ...data, token };\n } catch (err: any) {\n // The CMS nests the real error one level down:\n // `{ error: \"HTTPException\", detail: { error, errorDescription } }`.\n const beData = (err?.data ?? {}) as Record<string, any>;\n const detail = (beData.detail ?? {}) as Record<string, any>;\n const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;\n throw createError({\n statusCode: err?.response?.status || err?.statusCode || 500,\n message: message || 'IdP callback failed',\n data: beData,\n });\n }\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { defineEventHandler, createError, readBody, parseCookies } from 'h3';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { c as AUTH_ENDPOINT, b as HTTP_HEADER } from '../../chunks/auth.constant-DO7ZmsKg.js';
|
|
4
|
+
import { r as readSdkConfig } from '../../chunks/_shared-48T7q0V3.js';
|
|
5
|
+
import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant--64BDSPW.js';
|
|
6
|
+
|
|
7
|
+
const idpLink_post = defineEventHandler(async (event) => {
|
|
8
|
+
const { cmsUrl, clientId } = readSdkConfig(event);
|
|
9
|
+
if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
|
|
10
|
+
const body = await readBody(event).catch(() => ({}));
|
|
11
|
+
const provider = (body.provider ?? "").trim();
|
|
12
|
+
if (!provider) throw createError({ statusCode: 400, message: "provider is required" });
|
|
13
|
+
const cookies = parseCookies(event);
|
|
14
|
+
const token = cookies[TOKEN_STORAGE_KEY] || "";
|
|
15
|
+
if (!token) throw createError({ statusCode: 401, message: "Not authenticated" });
|
|
16
|
+
try {
|
|
17
|
+
return await $fetch(AUTH_ENDPOINT.idpLink(provider), {
|
|
18
|
+
baseURL: cmsUrl,
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
[HTTP_HEADER.CLIENT_ID]: clientId || "",
|
|
22
|
+
[HTTP_HEADER.AUTHORIZATION]: `Bearer ${token}`
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
} catch (err) {
|
|
26
|
+
const beData = err?.data ?? {};
|
|
27
|
+
const detail = beData.detail ?? {};
|
|
28
|
+
const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;
|
|
29
|
+
throw createError({
|
|
30
|
+
statusCode: err?.response?.status || err?.statusCode || 500,
|
|
31
|
+
message: message || "IdP link failed",
|
|
32
|
+
data: beData
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export { idpLink_post as default };
|
|
38
|
+
//# sourceMappingURL=idp-link.post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idp-link.post.js","sources":["../../../src/server/auth/idp-link.post.ts"],"sourcesContent":["import { defineEventHandler, readBody, parseCookies, createError } from 'h3';\nimport { $fetch } from 'ofetch';\nimport { AUTH_ENDPOINT } from '../../common/constants/auth.constant';\nimport { HTTP_HEADER } from '../../common/constants/http.constant';\nimport { readSdkConfig, TOKEN_STORAGE_KEY } from './_shared';\n\n/**\n * Thin auth proxy: POST /api/cms/idp-link → backend POST /api/auth/{provider}/link.\n *\n * Links the CURRENTLY signed-in CMS user to the IdP provider. The backend\n * requires an authenticated caller, so the httpOnly access-token cookie is\n * forwarded as `Authorization: Bearer <token>`.\n */\nexport default defineEventHandler(async (event) => {\n const { cmsUrl, clientId } = readSdkConfig(event);\n if (!cmsUrl) throw createError({ statusCode: 500, message: 'CMS URL not configured' });\n\n const body = (await readBody(event).catch(() => ({}))) as { provider?: string };\n const provider = (body.provider ?? '').trim();\n if (!provider) throw createError({ statusCode: 400, message: 'provider is required' });\n\n const cookies = parseCookies(event);\n const token = cookies[TOKEN_STORAGE_KEY] || '';\n if (!token) throw createError({ statusCode: 401, message: 'Not authenticated' });\n\n try {\n return await $fetch(AUTH_ENDPOINT.idpLink(provider), {\n baseURL: cmsUrl,\n method: 'POST',\n headers: {\n [HTTP_HEADER.CLIENT_ID]: clientId || '',\n [HTTP_HEADER.AUTHORIZATION]: `Bearer ${token}`,\n },\n });\n } catch (err: any) {\n // The CMS nests the real error one level down:\n // `{ error: \"HTTPException\", detail: { error, errorDescription } }`.\n const beData = (err?.data ?? {}) as Record<string, any>;\n const detail = (beData.detail ?? {}) as Record<string, any>;\n const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;\n throw createError({\n statusCode: err?.response?.status || err?.statusCode || 500,\n message: message || 'IdP link failed',\n data: beData,\n });\n }\n});\n"],"names":[],"mappings":";;;;;;AAaA,qBAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAS,GAAI,cAAc,KAAK,CAAA;AAChD,EAAA,IAAI,CAAC,QAAQ,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,wBAAA,EAA0B,CAAA;AAErF,EAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,KAAK,EAAE,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACpD,EAAA,MAAM,QAAA,GAAA,CAAY,IAAA,CAAK,QAAA,IAAY,EAAA,EAAI,IAAA,EAAK;AAC5C,EAAA,IAAI,CAAC,UAAU,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,sBAAA,EAAwB,CAAA;AAErF,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,iBAAiB,CAAA,IAAK,EAAA;AAC5C,EAAA,IAAI,CAAC,OAAO,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,mBAAA,EAAqB,CAAA;AAE/E,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,MAAA,CAAO,aAAA,CAAc,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAAA,MACnD,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,CAAC,WAAA,CAAY,SAAS,GAAG,QAAA,IAAY,EAAA;AAAA,QACrC,CAAC,WAAA,CAAY,aAAa,GAAG,UAAU,KAAK,CAAA;AAAA;AAC9C,KACD,CAAA;AAAA,EACH,SAAS,GAAA,EAAU;AAGjB,IAAA,MAAM,MAAA,GAAU,GAAA,EAAK,IAAA,IAAQ,EAAC;AAC9B,IAAA,MAAM,MAAA,GAAU,MAAA,CAAO,MAAA,IAAU,EAAC;AAClC,IAAA,MAAM,UAAU,MAAA,CAAO,gBAAA,IAAoB,OAAO,KAAA,IAAS,MAAA,CAAO,SAAS,GAAA,EAAK,OAAA;AAChF,IAAA,MAAM,WAAA,CAAY;AAAA,MAChB,UAAA,EAAY,GAAA,EAAK,QAAA,EAAU,MAAA,IAAU,KAAK,UAAA,IAAc,GAAA;AAAA,MACxD,SAAS,OAAA,IAAW,iBAAA;AAAA,MACpB,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineEventHandler, createError, getQuery, parseCookies, getRequestHeader } from 'h3';
|
|
2
|
+
import { $fetch } from 'ofetch';
|
|
3
|
+
import { b as HTTP_HEADER, c as AUTH_ENDPOINT } from '../../chunks/auth.constant-DO7ZmsKg.js';
|
|
4
|
+
import { r as readSdkConfig } from '../../chunks/_shared-48T7q0V3.js';
|
|
5
|
+
|
|
6
|
+
const idpLogin_get = defineEventHandler(async (event) => {
|
|
7
|
+
const { cmsUrl, clientId } = readSdkConfig(event);
|
|
8
|
+
if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
|
|
9
|
+
const query = getQuery(event);
|
|
10
|
+
const provider = (query.provider ?? "").trim();
|
|
11
|
+
const redirectUri = (query.redirect_uri ?? "").trim();
|
|
12
|
+
if (!provider) throw createError({ statusCode: 400, message: "provider is required" });
|
|
13
|
+
if (!redirectUri) throw createError({ statusCode: 400, message: "redirect_uri is required" });
|
|
14
|
+
const cookies = parseCookies(event);
|
|
15
|
+
const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || "";
|
|
16
|
+
try {
|
|
17
|
+
const data = await $fetch(AUTH_ENDPOINT.idpLogin(provider), {
|
|
18
|
+
baseURL: cmsUrl,
|
|
19
|
+
method: "GET",
|
|
20
|
+
query: { redirect_uri: redirectUri },
|
|
21
|
+
headers: {
|
|
22
|
+
[HTTP_HEADER.CLIENT_ID]: clientId || "",
|
|
23
|
+
[HTTP_HEADER.DEVICE_ID]: cookies.device_id || "",
|
|
24
|
+
[HTTP_HEADER.DEVICE_IP]: cookies.device_ip || "",
|
|
25
|
+
[HTTP_HEADER.USER_AGENT]: userAgent
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return data;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
const beData = err?.data ?? {};
|
|
31
|
+
const detail = beData.detail ?? {};
|
|
32
|
+
const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;
|
|
33
|
+
throw createError({
|
|
34
|
+
statusCode: err?.response?.status || err?.statusCode || 500,
|
|
35
|
+
message: message || "IdP login init failed",
|
|
36
|
+
data: beData
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export { idpLogin_get as default };
|
|
42
|
+
//# sourceMappingURL=idp-login.get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idp-login.get.js","sources":["../../../src/server/auth/idp-login.get.ts"],"sourcesContent":["import { defineEventHandler, parseCookies, getQuery, getRequestHeader, createError } from 'h3';\nimport { $fetch } from 'ofetch';\nimport { AUTH_ENDPOINT } from '../../common/constants/auth.constant';\nimport { HTTP_HEADER } from '../../common/constants/http.constant';\nimport { readSdkConfig } from './_shared';\n\n/**\n * Thin auth proxy: GET /api/cms/idp-login → backend GET /api/auth/{provider}/login.\n *\n * Initialises an IdP SSO login (Authorization Code + one-use state, TTL 600s).\n * The backend returns `{ authorization_url, state }`; no cookie is set here —\n * the CMS JWT is only minted on `/idp-callback`.\n */\nexport default defineEventHandler(async (event) => {\n const { cmsUrl, clientId } = readSdkConfig(event);\n if (!cmsUrl) throw createError({ statusCode: 500, message: 'CMS URL not configured' });\n\n const query = getQuery(event) as { provider?: string; redirect_uri?: string };\n const provider = (query.provider ?? '').trim();\n const redirectUri = (query.redirect_uri ?? '').trim();\n if (!provider) throw createError({ statusCode: 400, message: 'provider is required' });\n if (!redirectUri) throw createError({ statusCode: 400, message: 'redirect_uri is required' });\n\n const cookies = parseCookies(event);\n const userAgent = getRequestHeader(event, HTTP_HEADER.USER_AGENT) || '';\n\n try {\n const data = (await $fetch(AUTH_ENDPOINT.idpLogin(provider), {\n baseURL: cmsUrl,\n method: 'GET',\n query: { redirect_uri: redirectUri },\n headers: {\n [HTTP_HEADER.CLIENT_ID]: clientId || '',\n [HTTP_HEADER.DEVICE_ID]: cookies.device_id || '',\n [HTTP_HEADER.DEVICE_IP]: cookies.device_ip || '',\n [HTTP_HEADER.USER_AGENT]: userAgent,\n },\n })) as Record<string, unknown>;\n return data;\n } catch (err: any) {\n // The CMS nests the real error one level down:\n // `{ error: \"HTTPException\", detail: { error, errorDescription } }`.\n const beData = (err?.data ?? {}) as Record<string, any>;\n const detail = (beData.detail ?? {}) as Record<string, any>;\n const message = detail.errorDescription ?? detail.error ?? beData.error ?? err?.message;\n throw createError({\n statusCode: err?.response?.status || err?.statusCode || 500,\n message: message || 'IdP login init failed',\n data: beData,\n });\n }\n});\n"],"names":[],"mappings":";;;;;AAaA,qBAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAS,GAAI,cAAc,KAAK,CAAA;AAChD,EAAA,IAAI,CAAC,QAAQ,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,wBAAA,EAA0B,CAAA;AAErF,EAAA,MAAM,KAAA,GAAQ,SAAS,KAAK,CAAA;AAC5B,EAAA,MAAM,QAAA,GAAA,CAAY,KAAA,CAAM,QAAA,IAAY,EAAA,EAAI,IAAA,EAAK;AAC7C,EAAA,MAAM,WAAA,GAAA,CAAe,KAAA,CAAM,YAAA,IAAgB,EAAA,EAAI,IAAA,EAAK;AACpD,EAAA,IAAI,CAAC,UAAU,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,sBAAA,EAAwB,CAAA;AACrF,EAAA,IAAI,CAAC,aAAa,MAAM,WAAA,CAAY,EAAE,UAAA,EAAY,GAAA,EAAK,OAAA,EAAS,0BAAA,EAA4B,CAAA;AAE5F,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,KAAA,EAAO,WAAA,CAAY,UAAU,CAAA,IAAK,EAAA;AAErE,EAAA,IAAI;AACF,IAAA,MAAM,OAAQ,MAAM,MAAA,CAAO,aAAA,CAAc,QAAA,CAAS,QAAQ,CAAA,EAAG;AAAA,MAC3D,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,KAAA;AAAA,MACR,KAAA,EAAO,EAAE,YAAA,EAAc,WAAA,EAAY;AAAA,MACnC,OAAA,EAAS;AAAA,QACP,CAAC,WAAA,CAAY,SAAS,GAAG,QAAA,IAAY,EAAA;AAAA,QACrC,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,SAAS,GAAG,QAAQ,SAAA,IAAa,EAAA;AAAA,QAC9C,CAAC,WAAA,CAAY,UAAU,GAAG;AAAA;AAC5B,KACD,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAU;AAGjB,IAAA,MAAM,MAAA,GAAU,GAAA,EAAK,IAAA,IAAQ,EAAC;AAC9B,IAAA,MAAM,MAAA,GAAU,MAAA,CAAO,MAAA,IAAU,EAAC;AAClC,IAAA,MAAM,UAAU,MAAA,CAAO,gBAAA,IAAoB,OAAO,KAAA,IAAS,MAAA,CAAO,SAAS,GAAA,EAAK,OAAA;AAChF,IAAA,MAAM,WAAA,CAAY;AAAA,MAChB,UAAA,EAAY,GAAA,EAAK,QAAA,EAAU,MAAA,IAAU,KAAK,UAAA,IAAc,GAAA;AAAA,MACxD,SAAS,OAAA,IAAW,uBAAA;AAAA,MACpB,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|