doover-js 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -0
- package/dist/apis/_args.js +5 -5
- package/dist/apis/agents-api.d.ts +4 -4
- package/dist/apis/agents-api.js +2 -2
- package/dist/apis/aggregates-api.d.ts +4 -4
- package/dist/apis/aggregates-api.js +5 -5
- package/dist/apis/alarms-api.d.ts +2 -2
- package/dist/apis/alarms-api.js +3 -3
- package/dist/apis/channels-api.d.ts +3 -3
- package/dist/apis/channels-api.js +6 -6
- package/dist/apis/connections-api.d.ts +2 -2
- package/dist/apis/connections-api.js +6 -6
- package/dist/apis/messages-api.d.ts +4 -4
- package/dist/apis/messages-api.js +11 -11
- package/dist/apis/notifications-api.d.ts +2 -2
- package/dist/apis/notifications-api.js +4 -4
- package/dist/apis/organisations-api.d.ts +2 -2
- package/dist/apis/permissions-api.d.ts +2 -2
- package/dist/apis/permissions-api.js +3 -3
- package/dist/apis/processors-api.d.ts +2 -2
- package/dist/apis/turn-api.d.ts +2 -2
- package/dist/apis/users-api.d.ts +2 -2
- package/dist/auth/auth-store.d.ts +1 -1
- package/dist/auth/build-auth.d.ts +3 -3
- package/dist/auth/build-auth.js +8 -8
- package/dist/auth/cookie-auth.d.ts +1 -1
- package/dist/auth/cookie-auth.js +2 -2
- package/dist/auth/doover-auth.d.ts +2 -2
- package/dist/auth/doover-token-auth.d.ts +3 -3
- package/dist/auth/doover-token-auth.js +13 -13
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.js +15 -0
- package/dist/client/data-client.d.ts +17 -14
- package/dist/client/doover-client.d.ts +9 -7
- package/dist/client/doover-client.js +44 -42
- package/dist/client/errors.d.ts +2 -2
- package/dist/client/errors.js +4 -4
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +12 -0
- package/dist/client/local-agent-client.d.ts +3 -3
- package/dist/client/local-agent-client.js +19 -19
- package/dist/client/multiplex-client.d.ts +5 -5
- package/dist/client/multiplex-client.js +25 -25
- package/dist/client/multiplex-gateway.d.ts +3 -3
- package/dist/client/multiplex-merge.d.ts +1 -1
- package/dist/client/network-status.d.ts +17 -0
- package/dist/client/network-status.js +70 -0
- package/dist/client/offline-cache.d.ts +9 -4
- package/dist/client/offline-cache.js +34 -22
- package/dist/client/provenance.d.ts +1 -1
- package/dist/client/request-options.d.ts +1 -1
- package/dist/client/singleton.d.ts +2 -2
- package/dist/client/singleton.js +2 -2
- package/dist/client/status-tracker.d.ts +1 -1
- package/dist/esm/apis/_args.d.ts +16 -0
- package/dist/esm/apis/_args.js +27 -0
- package/dist/esm/apis/agents-api.d.ts +196 -0
- package/dist/esm/apis/agents-api.js +327 -0
- package/dist/esm/apis/aggregates-api.d.ts +67 -0
- package/dist/esm/apis/aggregates-api.js +64 -0
- package/dist/esm/apis/alarms-api.d.ts +48 -0
- package/dist/esm/apis/alarms-api.js +75 -0
- package/dist/esm/apis/channels-api.d.ts +83 -0
- package/dist/esm/apis/channels-api.js +65 -0
- package/dist/esm/apis/connections-api.d.ts +45 -0
- package/dist/esm/apis/connections-api.js +44 -0
- package/dist/esm/apis/messages-api.d.ts +128 -0
- package/dist/esm/apis/messages-api.js +179 -0
- package/dist/esm/apis/notifications-api.d.ts +94 -0
- package/dist/esm/apis/notifications-api.js +153 -0
- package/dist/esm/apis/organisations-api.d.ts +26 -0
- package/dist/esm/apis/organisations-api.js +41 -0
- package/dist/esm/apis/permissions-api.d.ts +17 -0
- package/dist/esm/apis/permissions-api.js +23 -0
- package/dist/esm/apis/processors-api.d.ts +56 -0
- package/dist/esm/apis/processors-api.js +97 -0
- package/dist/esm/apis/turn-api.d.ts +7 -0
- package/dist/esm/apis/turn-api.js +8 -0
- package/dist/esm/apis/users-api.d.ts +8 -0
- package/dist/esm/apis/users-api.js +9 -0
- package/dist/esm/auth/auth-profile.d.ts +45 -0
- package/dist/esm/auth/auth-profile.js +68 -0
- package/dist/esm/auth/auth-store.d.ts +14 -0
- package/dist/esm/auth/build-auth.d.ts +38 -0
- package/dist/esm/auth/build-auth.js +92 -0
- package/dist/esm/auth/cookie-auth.d.ts +91 -0
- package/dist/esm/auth/cookie-auth.js +196 -0
- package/dist/esm/auth/doover-auth.d.ts +52 -0
- package/dist/esm/auth/doover-auth.js +28 -0
- package/dist/esm/auth/doover-token-auth.d.ts +39 -0
- package/dist/esm/auth/doover-token-auth.js +217 -0
- package/dist/esm/auth/errors.d.ts +3 -0
- package/dist/esm/auth/errors.js +6 -0
- package/dist/esm/auth/index.d.ts +10 -0
- package/dist/esm/auth/index.js +6 -0
- package/dist/esm/auth/jwt.d.ts +6 -0
- package/dist/esm/auth/jwt.js +26 -0
- package/dist/esm/client/capabilities.d.ts +10 -0
- package/dist/esm/client/capabilities.js +42 -0
- package/dist/esm/client/data-client.d.ts +107 -0
- package/dist/esm/client/doover-client.d.ts +48 -0
- package/dist/esm/client/doover-client.js +96 -0
- package/dist/esm/client/errors.d.ts +32 -0
- package/dist/esm/client/errors.js +64 -0
- package/dist/esm/client/index.d.ts +6 -0
- package/dist/esm/client/index.js +3 -0
- package/dist/esm/client/local-agent-client.d.ts +65 -0
- package/dist/esm/client/local-agent-client.js +225 -0
- package/dist/esm/client/multiplex-client.d.ts +165 -0
- package/dist/esm/client/multiplex-client.js +842 -0
- package/dist/esm/client/multiplex-gateway.d.ts +49 -0
- package/dist/esm/client/multiplex-gateway.js +110 -0
- package/dist/esm/client/multiplex-merge.d.ts +12 -0
- package/dist/esm/client/multiplex-merge.js +38 -0
- package/dist/esm/client/network-status.d.ts +17 -0
- package/dist/esm/client/network-status.js +66 -0
- package/dist/esm/client/offline-cache.d.ts +167 -0
- package/dist/esm/client/offline-cache.js +769 -0
- package/dist/esm/client/provenance.d.ts +60 -0
- package/dist/esm/client/provenance.js +108 -0
- package/dist/esm/client/request-options.d.ts +23 -0
- package/dist/esm/client/request-options.js +23 -0
- package/dist/esm/client/singleton.d.ts +26 -0
- package/dist/esm/client/singleton.js +54 -0
- package/dist/esm/client/stats.d.ts +79 -0
- package/dist/esm/client/stats.js +155 -0
- package/dist/esm/client/status-tracker.d.ts +24 -0
- package/dist/esm/client/status-tracker.js +86 -0
- package/dist/esm/gateway/gateway-client.d.ts +86 -0
- package/dist/esm/gateway/gateway-client.js +463 -0
- package/dist/esm/gateway/index.d.ts +3 -0
- package/dist/esm/gateway/index.js +1 -0
- package/dist/esm/gateway/types.d.ts +142 -0
- package/dist/esm/http/errors.d.ts +19 -0
- package/dist/esm/http/errors.js +22 -0
- package/dist/esm/http/index.d.ts +3 -0
- package/dist/esm/http/index.js +2 -0
- package/dist/esm/http/rest-client.d.ts +64 -0
- package/dist/esm/http/rest-client.js +181 -0
- package/dist/esm/index.d.ts +64 -0
- package/dist/esm/index.js +38 -0
- package/dist/esm/node/config-manager.d.ts +34 -0
- package/dist/esm/node/config-manager.js +140 -0
- package/dist/esm/node/index.d.ts +1 -0
- package/dist/esm/node/index.js +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/react/context.d.ts +23 -0
- package/dist/esm/react/context.js +28 -0
- package/dist/esm/react/index.d.ts +38 -0
- package/dist/esm/react/index.js +21 -0
- package/dist/esm/react/messageRangeStore.d.ts +93 -0
- package/dist/esm/react/messageRangeStore.js +140 -0
- package/dist/esm/react/sharedQueryClient.d.ts +21 -0
- package/dist/esm/react/sharedQueryClient.js +35 -0
- package/dist/esm/react/useAgentChannel.d.ts +8 -0
- package/dist/esm/react/useAgentChannel.js +9 -0
- package/dist/esm/react/useAgentConnections.d.ts +8 -0
- package/dist/esm/react/useAgentConnections.js +20 -0
- package/dist/esm/react/useAgentTokenState.d.ts +70 -0
- package/dist/esm/react/useAgentTokenState.js +127 -0
- package/dist/esm/react/useChannelAggregate.d.ts +64 -0
- package/dist/esm/react/useChannelAggregate.js +77 -0
- package/dist/esm/react/useChannelMessage.d.ts +45 -0
- package/dist/esm/react/useChannelMessage.js +79 -0
- package/dist/esm/react/useChannelMessages.d.ts +83 -0
- package/dist/esm/react/useChannelMessages.js +214 -0
- package/dist/esm/react/useChannelSubscription.d.ts +27 -0
- package/dist/esm/react/useChannelSubscription.js +30 -0
- package/dist/esm/react/useClientStatus.d.ts +10 -0
- package/dist/esm/react/useClientStatus.js +19 -0
- package/dist/esm/react/useConnectionState.d.ts +26 -0
- package/dist/esm/react/useConnectionState.js +45 -0
- package/dist/esm/react/useDeviceMap.d.ts +109 -0
- package/dist/esm/react/useDeviceMap.js +59 -0
- package/dist/esm/react/useInvocationLogs.d.ts +23 -0
- package/dist/esm/react/useInvocationLogs.js +37 -0
- package/dist/esm/react/useMultiAgentAggregates.d.ts +38 -0
- package/dist/esm/react/useMultiAgentAggregates.js +104 -0
- package/dist/esm/react/useMultiAgentChannelMessages.d.ts +79 -0
- package/dist/esm/react/useMultiAgentChannelMessages.js +169 -0
- package/dist/esm/react/useOfflineStatus.d.ts +8 -0
- package/dist/esm/react/useOfflineStatus.js +37 -0
- package/dist/esm/react/useSendMessage.d.ts +16 -0
- package/dist/esm/react/useSendMessage.js +26 -0
- package/dist/esm/react/useSendRpc.d.ts +68 -0
- package/dist/esm/react/useSendRpc.js +164 -0
- package/dist/esm/react/useTurnCredentials.d.ts +12 -0
- package/dist/esm/react/useTurnCredentials.js +22 -0
- package/dist/esm/react/useUpdateAggregate.d.ts +27 -0
- package/dist/esm/react/useUpdateAggregate.js +39 -0
- package/dist/esm/react/useUpdateMessage.d.ts +38 -0
- package/dist/esm/react/useUpdateMessage.js +36 -0
- package/dist/esm/refine/index.d.ts +72 -0
- package/dist/esm/refine/index.js +215 -0
- package/dist/esm/rpc/errors.d.ts +10 -0
- package/dist/esm/rpc/errors.js +19 -0
- package/dist/esm/rpc/index.d.ts +3 -0
- package/dist/esm/rpc/index.js +2 -0
- package/dist/esm/rpc/rpc-dispatcher.d.ts +41 -0
- package/dist/esm/rpc/rpc-dispatcher.js +141 -0
- package/dist/esm/types/audit.d.ts +53 -0
- package/dist/esm/types/audit.js +11 -0
- package/dist/esm/types/batch.d.ts +85 -0
- package/dist/esm/types/batch.js +42 -0
- package/dist/esm/types/common.d.ts +250 -0
- package/dist/esm/types/connection.d.ts +72 -0
- package/dist/esm/types/connection.js +7 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/esm/types/openapi.d.ts +195 -0
- package/dist/esm/types/provenance.d.ts +45 -0
- package/dist/esm/types/viewer.d.ts +122 -0
- package/dist/esm/utils/snowflake.d.ts +21 -0
- package/dist/esm/utils/snowflake.js +33 -0
- package/dist/esm/viewer/doover-data-provider.d.ts +90 -0
- package/dist/esm/viewer/doover-data-provider.js +189 -0
- package/dist/esm/viewer/path-parsing.d.ts +5 -0
- package/dist/esm/viewer/path-parsing.js +35 -0
- package/dist/gateway/gateway-client.d.ts +5 -5
- package/dist/gateway/gateway-client.js +5 -5
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +5 -0
- package/dist/gateway/types.d.ts +1 -1
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +9 -0
- package/dist/http/rest-client.d.ts +5 -3
- package/dist/http/rest-client.js +2 -2
- package/dist/index.d.ts +64 -62
- package/dist/index.js +92 -89
- package/dist/node/config-manager.d.ts +2 -2
- package/dist/node/config-manager.js +5 -5
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +2 -2
- package/dist/react/context.d.ts +1 -1
- package/dist/react/index.d.ts +38 -38
- package/dist/react/index.js +59 -59
- package/dist/react/messageRangeStore.d.ts +1 -1
- package/dist/react/useAgentChannel.d.ts +3 -3
- package/dist/react/useAgentChannel.js +2 -2
- package/dist/react/useAgentConnections.d.ts +1 -1
- package/dist/react/useAgentConnections.js +2 -2
- package/dist/react/useAgentTokenState.d.ts +3 -3
- package/dist/react/useAgentTokenState.js +8 -8
- package/dist/react/useChannelAggregate.d.ts +3 -3
- package/dist/react/useChannelAggregate.js +8 -8
- package/dist/react/useChannelMessage.d.ts +2 -2
- package/dist/react/useChannelMessage.js +4 -4
- package/dist/react/useChannelMessages.d.ts +3 -3
- package/dist/react/useChannelMessages.js +10 -10
- package/dist/react/useChannelSubscription.d.ts +2 -2
- package/dist/react/useChannelSubscription.js +2 -2
- package/dist/react/useClientStatus.d.ts +1 -1
- package/dist/react/useClientStatus.js +2 -2
- package/dist/react/useConnectionState.js +2 -2
- package/dist/react/useDeviceMap.js +2 -2
- package/dist/react/useInvocationLogs.d.ts +1 -1
- package/dist/react/useInvocationLogs.js +2 -2
- package/dist/react/useMultiAgentAggregates.d.ts +1 -1
- package/dist/react/useMultiAgentAggregates.js +5 -5
- package/dist/react/useMultiAgentChannelMessages.d.ts +1 -1
- package/dist/react/useMultiAgentChannelMessages.js +2 -2
- package/dist/react/useOfflineStatus.d.ts +2 -2
- package/dist/react/useOfflineStatus.js +31 -17
- package/dist/react/useSendMessage.d.ts +2 -2
- package/dist/react/useSendMessage.js +2 -2
- package/dist/react/useSendRpc.d.ts +2 -2
- package/dist/react/useSendRpc.js +2 -2
- package/dist/react/useTurnCredentials.d.ts +2 -2
- package/dist/react/useTurnCredentials.js +2 -2
- package/dist/react/useUpdateAggregate.d.ts +3 -3
- package/dist/react/useUpdateAggregate.js +4 -4
- package/dist/react/useUpdateMessage.d.ts +2 -2
- package/dist/react/useUpdateMessage.js +2 -2
- package/dist/refine/index.d.ts +1 -1
- package/dist/rpc/errors.d.ts +1 -1
- package/dist/rpc/index.d.ts +3 -0
- package/dist/rpc/index.js +7 -0
- package/dist/rpc/rpc-dispatcher.d.ts +4 -4
- package/dist/rpc/rpc-dispatcher.js +2 -2
- package/dist/types/common.d.ts +1 -1
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +2 -0
- package/dist/types/openapi.d.ts +1 -1
- package/dist/types/viewer.d.ts +2 -2
- package/dist/viewer/doover-data-provider.d.ts +10 -10
- package/dist/viewer/doover-data-provider.js +25 -25
- package/dist/viewer/path-parsing.d.ts +1 -1
- package/package.json +795 -8
- package/dist/test/api-args.test.js +0 -48
- package/dist/test/api-overloads.test.d.ts +0 -9
- package/dist/test/api-overloads.test.js +0 -330
- package/dist/test/apis.test.js +0 -408
- package/dist/test/auth.test.js +0 -708
- package/dist/test/batch-apis.test.js +0 -183
- package/dist/test/capabilities.test.js +0 -27
- package/dist/test/config-manager.test.js +0 -160
- package/dist/test/data-client-errors.test.js +0 -24
- package/dist/test/data-client-shape.test.js +0 -28
- package/dist/test/doover-client-dataclient.test.d.ts +0 -1
- package/dist/test/doover-client-dataclient.test.js +0 -58
- package/dist/test/doover-client-provenance.test.d.ts +0 -1
- package/dist/test/doover-client-provenance.test.js +0 -32
- package/dist/test/doover-client.test.d.ts +0 -1
- package/dist/test/doover-client.test.js +0 -42
- package/dist/test/doover-data-provider.test.d.ts +0 -1
- package/dist/test/doover-data-provider.test.js +0 -657
- package/dist/test/exports.test.d.ts +0 -1
- package/dist/test/exports.test.js +0 -80
- package/dist/test/gateway-client.test.d.ts +0 -1
- package/dist/test/gateway-client.test.js +0 -474
- package/dist/test/gateway-provenance.test.d.ts +0 -1
- package/dist/test/gateway-provenance.test.js +0 -29
- package/dist/test/gateway-subscriptions.test.d.ts +0 -1
- package/dist/test/gateway-subscriptions.test.js +0 -95
- package/dist/test/helpers.d.ts +0 -32
- package/dist/test/helpers.js +0 -115
- package/dist/test/local-agent-client.test.d.ts +0 -1
- package/dist/test/local-agent-client.test.js +0 -202
- package/dist/test/message-range-store.test.d.ts +0 -1
- package/dist/test/message-range-store.test.js +0 -183
- package/dist/test/multiplex-capabilities.test.d.ts +0 -1
- package/dist/test/multiplex-capabilities.test.js +0 -37
- package/dist/test/multiplex-conflicts.test.d.ts +0 -1
- package/dist/test/multiplex-conflicts.test.js +0 -35
- package/dist/test/multiplex-gateway.test.d.ts +0 -1
- package/dist/test/multiplex-gateway.test.js +0 -103
- package/dist/test/multiplex-merge.test.d.ts +0 -1
- package/dist/test/multiplex-merge.test.js +0 -19
- package/dist/test/multiplex-noncore.test.d.ts +0 -1
- package/dist/test/multiplex-noncore.test.js +0 -82
- package/dist/test/multiplex-passthrough.test.d.ts +0 -1
- package/dist/test/multiplex-passthrough.test.js +0 -35
- package/dist/test/multiplex-reads.test.d.ts +0 -1
- package/dist/test/multiplex-reads.test.js +0 -87
- package/dist/test/multiplex-registry.test.d.ts +0 -1
- package/dist/test/multiplex-registry.test.js +0 -81
- package/dist/test/multiplex-routing.test.d.ts +0 -1
- package/dist/test/multiplex-routing.test.js +0 -45
- package/dist/test/multiplex-status.test.d.ts +0 -1
- package/dist/test/multiplex-status.test.js +0 -63
- package/dist/test/multiplex-writes.test.d.ts +0 -1
- package/dist/test/multiplex-writes.test.js +0 -93
- package/dist/test/offline-cache.test.d.ts +0 -1
- package/dist/test/offline-cache.test.js +0 -289
- package/dist/test/provenance-regression.test.d.ts +0 -1
- package/dist/test/provenance-regression.test.js +0 -45
- package/dist/test/provenance-stamper.test.d.ts +0 -1
- package/dist/test/provenance-stamper.test.js +0 -41
- package/dist/test/provenance-type.test.d.ts +0 -1
- package/dist/test/provenance-type.test.js +0 -15
- package/dist/test/react-channel-messages-forward.test.d.ts +0 -1
- package/dist/test/react-channel-messages-forward.test.js +0 -139
- package/dist/test/react-channel-messages-range.test.d.ts +0 -1
- package/dist/test/react-channel-messages-range.test.js +0 -109
- package/dist/test/react-client-status.test.d.ts +0 -1
- package/dist/test/react-client-status.test.js +0 -35
- package/dist/test/react-dataclient.test.d.ts +0 -1
- package/dist/test/react-dataclient.test.js +0 -28
- package/dist/test/react-exports.test.d.ts +0 -1
- package/dist/test/react-exports.test.js +0 -46
- package/dist/test/react-multiagent-messages.test.d.ts +0 -1
- package/dist/test/react-multiagent-messages.test.js +0 -113
- package/dist/test/react-sources-option.test.d.ts +0 -1
- package/dist/test/react-sources-option.test.js +0 -41
- package/dist/test/react.test.d.ts +0 -1
- package/dist/test/react.test.js +0 -482
- package/dist/test/refine.test.d.ts +0 -1
- package/dist/test/refine.test.js +0 -71
- package/dist/test/rest-client.test.d.ts +0 -1
- package/dist/test/rest-client.test.js +0 -197
- package/dist/test/rpc-dispatcher.test.d.ts +0 -1
- package/dist/test/rpc-dispatcher.test.js +0 -251
- package/dist/test/singleton.test.d.ts +0 -1
- package/dist/test/singleton.test.js +0 -62
- package/dist/test/stats-rpc.test.d.ts +0 -1
- package/dist/test/stats-rpc.test.js +0 -69
- package/dist/test/status-tracker.test.d.ts +0 -1
- package/dist/test/status-tracker.test.js +0 -85
- package/dist/test/users-api.test.d.ts +0 -1
- package/dist/test/users-api.test.js +0 -19
- package/dist/test/utils.test.d.ts +0 -1
- package/dist/test/utils.test.js +0 -64
- /package/dist/{test/api-args.test.d.ts → esm/auth/auth-store.js} +0 -0
- /package/dist/{test/apis.test.d.ts → esm/client/data-client.js} +0 -0
- /package/dist/{test/auth.test.d.ts → esm/gateway/types.js} +0 -0
- /package/dist/{test/batch-apis.test.d.ts → esm/types/common.js} +0 -0
- /package/dist/{test/capabilities.test.d.ts → esm/types/index.js} +0 -0
- /package/dist/{test/config-manager.test.d.ts → esm/types/openapi.js} +0 -0
- /package/dist/{test/data-client-errors.test.d.ts → esm/types/provenance.js} +0 -0
- /package/dist/{test/data-client-shape.test.d.ts → esm/types/viewer.js} +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AuthProfile } from "./auth-profile.js";
|
|
2
|
+
/**
|
|
3
|
+
* Structural interface for profile stores accepted by auth classes.
|
|
4
|
+
* Implementations may be backed by files (ConfigManager in the Node subpath)
|
|
5
|
+
* or by in-memory stores for testing.
|
|
6
|
+
*/
|
|
7
|
+
export interface AuthProfileStore {
|
|
8
|
+
currentProfile: string | null;
|
|
9
|
+
current: AuthProfile | null;
|
|
10
|
+
get(profileName: string): AuthProfile | undefined;
|
|
11
|
+
create(entry: AuthProfile): void;
|
|
12
|
+
delete(profileName: string): void;
|
|
13
|
+
write(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AuthProfile } from "./auth-profile.js";
|
|
2
|
+
import type { AuthProfileStore } from "./auth-store.js";
|
|
3
|
+
import { DooverAuth } from "./doover-auth.js";
|
|
4
|
+
/**
|
|
5
|
+
* Raw auth inputs that can be provided in client configs.
|
|
6
|
+
*
|
|
7
|
+
* If `auth` is provided it is used as-is and raw inputs must not be combined
|
|
8
|
+
* with it. Otherwise these fields are used to build the appropriate auth
|
|
9
|
+
* instance automatically.
|
|
10
|
+
*/
|
|
11
|
+
export interface AuthConfig {
|
|
12
|
+
auth?: DooverAuth;
|
|
13
|
+
profile?: string | AuthProfile;
|
|
14
|
+
configManager?: AuthProfileStore;
|
|
15
|
+
token?: string | null;
|
|
16
|
+
tokenExpires?: Date | number | null;
|
|
17
|
+
refreshToken?: string | null;
|
|
18
|
+
refreshTokenId?: string | null;
|
|
19
|
+
authServerUrl?: string | null;
|
|
20
|
+
authServerClientId?: string | null;
|
|
21
|
+
}
|
|
22
|
+
/** Fetch implementation to thread through to DooverTokenAuth. */
|
|
23
|
+
interface BuildAuthOptions extends AuthConfig {
|
|
24
|
+
fetchImpl?: typeof fetch;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a `DooverAuth` instance from the provided configuration.
|
|
28
|
+
*
|
|
29
|
+
* Rules:
|
|
30
|
+
* 1. If `auth` is provided it is returned as-is.
|
|
31
|
+
* 2. If any token material is present, build `DooverTokenAuth`.
|
|
32
|
+
* 3. If `profile` is an `AuthProfile`, use it to seed a `DooverTokenAuth`.
|
|
33
|
+
* 4. If `profile` is a string, look it up via `configManager`.
|
|
34
|
+
* 5. Otherwise fall back to `CookieAuth`, refresh-capable when
|
|
35
|
+
* `authServerUrl` is known.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildAuth(options: BuildAuthOptions): DooverAuth;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { CookieAuth } from "./cookie-auth.js";
|
|
2
|
+
import { DooverTokenAuth } from "./doover-token-auth.js";
|
|
3
|
+
import { DooverAuthError } from "./errors.js";
|
|
4
|
+
const TOKEN_FIELDS = [
|
|
5
|
+
"token",
|
|
6
|
+
"tokenExpires",
|
|
7
|
+
"refreshToken",
|
|
8
|
+
"refreshTokenId",
|
|
9
|
+
"authServerUrl",
|
|
10
|
+
"authServerClientId",
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* The subset of `TOKEN_FIELDS` that actually implies bearer-token auth.
|
|
14
|
+
*
|
|
15
|
+
* `authServerUrl` / `authServerClientId` describe *where* to refresh, not what
|
|
16
|
+
* we hold: on their own they now configure a refresh-capable `CookieAuth`
|
|
17
|
+
* (a browser session in an app that knows its auth server), which is far more
|
|
18
|
+
* useful than the tokenless `DooverTokenAuth` they used to produce — that
|
|
19
|
+
* instance could only ever throw "missing refreshToken" on first use.
|
|
20
|
+
*/
|
|
21
|
+
const TOKEN_MATERIAL_FIELDS = [
|
|
22
|
+
"token",
|
|
23
|
+
"tokenExpires",
|
|
24
|
+
"refreshToken",
|
|
25
|
+
"refreshTokenId",
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Build a `DooverAuth` instance from the provided configuration.
|
|
29
|
+
*
|
|
30
|
+
* Rules:
|
|
31
|
+
* 1. If `auth` is provided it is returned as-is.
|
|
32
|
+
* 2. If any token material is present, build `DooverTokenAuth`.
|
|
33
|
+
* 3. If `profile` is an `AuthProfile`, use it to seed a `DooverTokenAuth`.
|
|
34
|
+
* 4. If `profile` is a string, look it up via `configManager`.
|
|
35
|
+
* 5. Otherwise fall back to `CookieAuth`, refresh-capable when
|
|
36
|
+
* `authServerUrl` is known.
|
|
37
|
+
*/
|
|
38
|
+
export function buildAuth(options) {
|
|
39
|
+
if (options.auth) {
|
|
40
|
+
// Validate mutual exclusivity.
|
|
41
|
+
const hasRaw = TOKEN_FIELDS.some((k) => options[k] !== undefined);
|
|
42
|
+
if (hasRaw || options.profile !== undefined || options.configManager !== undefined) {
|
|
43
|
+
throw new DooverAuthError("Cannot combine 'auth' with raw auth config fields (token, profile, configManager, etc.)");
|
|
44
|
+
}
|
|
45
|
+
return options.auth;
|
|
46
|
+
}
|
|
47
|
+
// Resolve the profile object.
|
|
48
|
+
let resolvedProfile = null;
|
|
49
|
+
if (typeof options.profile === "string") {
|
|
50
|
+
if (!options.configManager) {
|
|
51
|
+
throw new DooverAuthError("A 'configManager' (AuthProfileStore) is required when 'profile' is a string. " +
|
|
52
|
+
"Use the doover-js/node subpath to import ConfigManager, or provide an AuthProfile directly.");
|
|
53
|
+
}
|
|
54
|
+
resolvedProfile = options.configManager.get(options.profile) ?? null;
|
|
55
|
+
if (!resolvedProfile) {
|
|
56
|
+
throw new DooverAuthError(`Profile '${options.profile}' not found in the config manager`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (options.profile instanceof Object && "profile" in options.profile) {
|
|
60
|
+
// AuthProfile instance
|
|
61
|
+
resolvedProfile = options.profile;
|
|
62
|
+
}
|
|
63
|
+
// Determine whether we need token auth.
|
|
64
|
+
const hasTokenInput = TOKEN_MATERIAL_FIELDS.some((k) => options[k] !== undefined);
|
|
65
|
+
const profileHasToken = resolvedProfile?.token != null;
|
|
66
|
+
if (!hasTokenInput && !profileHasToken) {
|
|
67
|
+
// No token data at all — fall back to cookie auth, which can still renew
|
|
68
|
+
// the session when the app has told us where its auth server lives.
|
|
69
|
+
const auth = new CookieAuth({
|
|
70
|
+
authServerUrl: options.authServerUrl ?? resolvedProfile?.authServerUrl ?? null,
|
|
71
|
+
fetchImpl: options.fetchImpl,
|
|
72
|
+
});
|
|
73
|
+
if (resolvedProfile) {
|
|
74
|
+
auth.attachProfile(resolvedProfile, options.configManager);
|
|
75
|
+
}
|
|
76
|
+
return auth;
|
|
77
|
+
}
|
|
78
|
+
// Build DooverTokenAuth with explicit fields overriding profile values.
|
|
79
|
+
const auth = new DooverTokenAuth({
|
|
80
|
+
token: options.token ?? undefined,
|
|
81
|
+
tokenExpires: options.tokenExpires ?? undefined,
|
|
82
|
+
refreshToken: options.refreshToken ?? undefined,
|
|
83
|
+
refreshTokenId: options.refreshTokenId ?? undefined,
|
|
84
|
+
authServerUrl: options.authServerUrl ?? undefined,
|
|
85
|
+
authServerClientId: options.authServerClientId ?? undefined,
|
|
86
|
+
fetchImpl: options.fetchImpl,
|
|
87
|
+
});
|
|
88
|
+
if (resolvedProfile) {
|
|
89
|
+
auth.attachProfile(resolvedProfile, options.configManager);
|
|
90
|
+
}
|
|
91
|
+
return auth;
|
|
92
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
export interface CookieAuthOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Base URL of the auth server that serves the hosted-backend refresh
|
|
5
|
+
* endpoint. Required for any refresh behaviour; without it `CookieAuth`
|
|
6
|
+
* behaves exactly as it always has (no refresh, no recovery).
|
|
7
|
+
*/
|
|
8
|
+
authServerUrl?: string | null;
|
|
9
|
+
/** Refresh endpoint path. Defaults to `/app/refresh/`. */
|
|
10
|
+
refreshPath?: string;
|
|
11
|
+
/** Name of the access-token expiry cookie. Defaults to `app.at_exp`. */
|
|
12
|
+
accessTokenExpiryCookieName?: string;
|
|
13
|
+
/** Override `fetch` (tests, native hosts). */
|
|
14
|
+
fetchImpl?: typeof fetch;
|
|
15
|
+
/** Override how the cookie string is read. Defaults to `document.cookie`. */
|
|
16
|
+
cookieReader?: () => string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Cookie-based auth — the default browser strategy.
|
|
20
|
+
*
|
|
21
|
+
* Relies on ambient cookies (`credentials: "include"`) and does not add any
|
|
22
|
+
* `Authorization` header. The access token itself is httpOnly and invisible to
|
|
23
|
+
* JS; the only readable part of the session is a companion expiry cookie
|
|
24
|
+
* (`app.at_exp`).
|
|
25
|
+
*
|
|
26
|
+
* ## Why this refreshes
|
|
27
|
+
*
|
|
28
|
+
* The FusionAuth React SDK's auto-refresh is a single `setTimeout` per token.
|
|
29
|
+
* A browser that suspends the tab (backgrounded, laptop asleep) never fires it,
|
|
30
|
+
* so the tab wakes with an expired access-token cookie and every request 401s —
|
|
31
|
+
* even though the refresh token itself is usually still valid. Rather than
|
|
32
|
+
* leaving every browser app to work around that on its own, `CookieAuth`
|
|
33
|
+
* handles it whenever `authServerUrl` is configured: `ensureReady` renews an
|
|
34
|
+
* already-expired token before a request goes out (which also covers gateway
|
|
35
|
+
* reconnects, since `GatewayClient` awaits it before opening a socket), and
|
|
36
|
+
* `handleUnauthorized` lets `RestClient` replay a 401 once after a renewal.
|
|
37
|
+
*/
|
|
38
|
+
export declare class CookieAuth extends DooverAuth {
|
|
39
|
+
private readonly authServerUrl;
|
|
40
|
+
private readonly refreshPath;
|
|
41
|
+
private readonly expiryCookieName;
|
|
42
|
+
private readonly fetchImpl;
|
|
43
|
+
private readonly cookieReader;
|
|
44
|
+
private refreshInFlight;
|
|
45
|
+
private lastAttempt;
|
|
46
|
+
constructor(options?: CookieAuthOptions);
|
|
47
|
+
getHttpHeaders(): Promise<Record<string, string>>;
|
|
48
|
+
getFetchCredentials(): RequestCredentials;
|
|
49
|
+
prepareWebSocket(url: string, _canUseHeaders: boolean): Promise<{
|
|
50
|
+
url: string;
|
|
51
|
+
headers?: Record<string, string>;
|
|
52
|
+
}>;
|
|
53
|
+
setToken(_token: string | null, _tokenExpires?: Date | number | null): void;
|
|
54
|
+
setRefreshToken(_refreshToken: string | null): void;
|
|
55
|
+
/**
|
|
56
|
+
* Renew the access token when it has already expired, so the request that
|
|
57
|
+
* follows isn't a guaranteed 401. A token that is merely close to expiry is
|
|
58
|
+
* left alone: requests must not block on a refresh they don't need, and
|
|
59
|
+
* `handleUnauthorized` is there for the race.
|
|
60
|
+
*/
|
|
61
|
+
ensureReady(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Called by `RestClient` after a 401. A successful refresh means the request
|
|
64
|
+
* is worth replaying once.
|
|
65
|
+
*/
|
|
66
|
+
handleUnauthorized(): Promise<boolean>;
|
|
67
|
+
/** Expiry of the current access token, or `null` if there is no session. */
|
|
68
|
+
getAccessTokenExpiry(): Date | null;
|
|
69
|
+
/** True when a session cookie exists and has not yet expired. */
|
|
70
|
+
isAccessTokenValid(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* True when the access token expires within `thresholdMs` (or already has).
|
|
73
|
+
* Apps use this to decide whether a `visibilitychange` is worth a proactive
|
|
74
|
+
* refresh. False when there is no session at all — nothing to refresh.
|
|
75
|
+
*/
|
|
76
|
+
isAccessTokenStale(thresholdMs?: number): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Refresh the access token, returning whether a valid one is now in place.
|
|
79
|
+
* Concurrent callers share one request, and the result is reused briefly so
|
|
80
|
+
* a burst of 401s costs a single round-trip.
|
|
81
|
+
*
|
|
82
|
+
* Safe to call directly — e.g. from a `visibilitychange` handler when
|
|
83
|
+
* {@link isAccessTokenStale} says the token is nearly up.
|
|
84
|
+
*/
|
|
85
|
+
refreshAccessToken(): Promise<boolean>;
|
|
86
|
+
private canRefresh;
|
|
87
|
+
private performRefresh;
|
|
88
|
+
/** The expiry cookie in epoch milliseconds, or `null` when absent. */
|
|
89
|
+
private readExpiryCookie;
|
|
90
|
+
private readCookieString;
|
|
91
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
/** Default FusionAuth hosted-backend refresh endpoint. */
|
|
3
|
+
const DEFAULT_REFRESH_PATH = "/app/refresh/";
|
|
4
|
+
/** Default name of the cookie holding the access token's expiry (Unix seconds). */
|
|
5
|
+
const DEFAULT_EXPIRY_COOKIE = "app.at_exp";
|
|
6
|
+
/**
|
|
7
|
+
* How long a refresh result is reused. Collapses the burst of callers that all
|
|
8
|
+
* discover an expired token at the same moment (every queued request 401-ing
|
|
9
|
+
* after a tab wakes up), and — more importantly — stops a *failed* refresh from
|
|
10
|
+
* being retried in a tight loop.
|
|
11
|
+
*/
|
|
12
|
+
const ATTEMPT_TTL_MS = 5000;
|
|
13
|
+
/**
|
|
14
|
+
* Cookie-based auth — the default browser strategy.
|
|
15
|
+
*
|
|
16
|
+
* Relies on ambient cookies (`credentials: "include"`) and does not add any
|
|
17
|
+
* `Authorization` header. The access token itself is httpOnly and invisible to
|
|
18
|
+
* JS; the only readable part of the session is a companion expiry cookie
|
|
19
|
+
* (`app.at_exp`).
|
|
20
|
+
*
|
|
21
|
+
* ## Why this refreshes
|
|
22
|
+
*
|
|
23
|
+
* The FusionAuth React SDK's auto-refresh is a single `setTimeout` per token.
|
|
24
|
+
* A browser that suspends the tab (backgrounded, laptop asleep) never fires it,
|
|
25
|
+
* so the tab wakes with an expired access-token cookie and every request 401s —
|
|
26
|
+
* even though the refresh token itself is usually still valid. Rather than
|
|
27
|
+
* leaving every browser app to work around that on its own, `CookieAuth`
|
|
28
|
+
* handles it whenever `authServerUrl` is configured: `ensureReady` renews an
|
|
29
|
+
* already-expired token before a request goes out (which also covers gateway
|
|
30
|
+
* reconnects, since `GatewayClient` awaits it before opening a socket), and
|
|
31
|
+
* `handleUnauthorized` lets `RestClient` replay a 401 once after a renewal.
|
|
32
|
+
*/
|
|
33
|
+
export class CookieAuth extends DooverAuth {
|
|
34
|
+
constructor(options = {}) {
|
|
35
|
+
super();
|
|
36
|
+
this.refreshInFlight = null;
|
|
37
|
+
this.lastAttempt = null;
|
|
38
|
+
this.authServerUrl = options.authServerUrl ?? null;
|
|
39
|
+
this.refreshPath = options.refreshPath ?? DEFAULT_REFRESH_PATH;
|
|
40
|
+
this.expiryCookieName =
|
|
41
|
+
options.accessTokenExpiryCookieName ?? DEFAULT_EXPIRY_COOKIE;
|
|
42
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
43
|
+
this.cookieReader = options.cookieReader ?? null;
|
|
44
|
+
}
|
|
45
|
+
// ------------------------------------------------------------------
|
|
46
|
+
// DooverAuth interface
|
|
47
|
+
// ------------------------------------------------------------------
|
|
48
|
+
async getHttpHeaders() {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
getFetchCredentials() {
|
|
52
|
+
return "include";
|
|
53
|
+
}
|
|
54
|
+
async prepareWebSocket(url, _canUseHeaders) {
|
|
55
|
+
// Cookie auth relies on ambient cookies — no URL or header changes.
|
|
56
|
+
return { url };
|
|
57
|
+
}
|
|
58
|
+
setToken(_token, _tokenExpires) {
|
|
59
|
+
// No-op for cookie auth — the token lives in an httpOnly cookie.
|
|
60
|
+
}
|
|
61
|
+
setRefreshToken(_refreshToken) {
|
|
62
|
+
// No-op for cookie auth — the refresh token lives in an httpOnly cookie.
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Renew the access token when it has already expired, so the request that
|
|
66
|
+
* follows isn't a guaranteed 401. A token that is merely close to expiry is
|
|
67
|
+
* left alone: requests must not block on a refresh they don't need, and
|
|
68
|
+
* `handleUnauthorized` is there for the race.
|
|
69
|
+
*/
|
|
70
|
+
async ensureReady() {
|
|
71
|
+
if (!this.canRefresh()) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (this.isAccessTokenValid()) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// A failed refresh is not fatal here — let the request go out and be
|
|
78
|
+
// handled by `handleUnauthorized` / the caller's error handling.
|
|
79
|
+
await this.refreshAccessToken();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Called by `RestClient` after a 401. A successful refresh means the request
|
|
83
|
+
* is worth replaying once.
|
|
84
|
+
*/
|
|
85
|
+
async handleUnauthorized() {
|
|
86
|
+
if (!this.canRefresh()) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return this.refreshAccessToken();
|
|
90
|
+
}
|
|
91
|
+
// ------------------------------------------------------------------
|
|
92
|
+
// Public helpers — apps need these for their own lifecycle hooks
|
|
93
|
+
// ------------------------------------------------------------------
|
|
94
|
+
/** Expiry of the current access token, or `null` if there is no session. */
|
|
95
|
+
getAccessTokenExpiry() {
|
|
96
|
+
const expiryMs = this.readExpiryCookie();
|
|
97
|
+
return expiryMs == null ? null : new Date(expiryMs);
|
|
98
|
+
}
|
|
99
|
+
/** True when a session cookie exists and has not yet expired. */
|
|
100
|
+
isAccessTokenValid() {
|
|
101
|
+
const expiryMs = this.readExpiryCookie();
|
|
102
|
+
return expiryMs != null && expiryMs > Date.now();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* True when the access token expires within `thresholdMs` (or already has).
|
|
106
|
+
* Apps use this to decide whether a `visibilitychange` is worth a proactive
|
|
107
|
+
* refresh. False when there is no session at all — nothing to refresh.
|
|
108
|
+
*/
|
|
109
|
+
isAccessTokenStale(thresholdMs = 60000) {
|
|
110
|
+
const expiryMs = this.readExpiryCookie();
|
|
111
|
+
if (expiryMs == null) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return expiryMs - Date.now() < thresholdMs;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Refresh the access token, returning whether a valid one is now in place.
|
|
118
|
+
* Concurrent callers share one request, and the result is reused briefly so
|
|
119
|
+
* a burst of 401s costs a single round-trip.
|
|
120
|
+
*
|
|
121
|
+
* Safe to call directly — e.g. from a `visibilitychange` handler when
|
|
122
|
+
* {@link isAccessTokenStale} says the token is nearly up.
|
|
123
|
+
*/
|
|
124
|
+
async refreshAccessToken() {
|
|
125
|
+
if (!this.canRefresh()) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (this.refreshInFlight) {
|
|
129
|
+
return this.refreshInFlight;
|
|
130
|
+
}
|
|
131
|
+
// No expiry cookie means we were never logged in, or have since logged
|
|
132
|
+
// out. The refresh endpoint would just 400.
|
|
133
|
+
if (this.readExpiryCookie() == null) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (this.lastAttempt && Date.now() - this.lastAttempt.at < ATTEMPT_TTL_MS) {
|
|
137
|
+
return this.lastAttempt.result;
|
|
138
|
+
}
|
|
139
|
+
const inFlight = this.performRefresh().then((result) => {
|
|
140
|
+
this.lastAttempt = { result, at: Date.now() };
|
|
141
|
+
this.refreshInFlight = null;
|
|
142
|
+
return result;
|
|
143
|
+
});
|
|
144
|
+
this.refreshInFlight = inFlight;
|
|
145
|
+
return inFlight;
|
|
146
|
+
}
|
|
147
|
+
// ------------------------------------------------------------------
|
|
148
|
+
// Internal
|
|
149
|
+
// ------------------------------------------------------------------
|
|
150
|
+
canRefresh() {
|
|
151
|
+
return this.authServerUrl != null && this.authServerUrl !== "";
|
|
152
|
+
}
|
|
153
|
+
async performRefresh() {
|
|
154
|
+
const url = `${this.authServerUrl}${this.refreshPath}`;
|
|
155
|
+
try {
|
|
156
|
+
const response = await this.fetchImpl(url, {
|
|
157
|
+
method: "POST",
|
|
158
|
+
credentials: "include",
|
|
159
|
+
headers: { "Content-Type": "text/plain" },
|
|
160
|
+
});
|
|
161
|
+
return response.ok;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Offline, DNS failure, blocked request — indistinguishable from here,
|
|
165
|
+
// and all mean "no new token".
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** The expiry cookie in epoch milliseconds, or `null` when absent. */
|
|
170
|
+
readExpiryCookie() {
|
|
171
|
+
const cookieString = this.readCookieString();
|
|
172
|
+
if (!cookieString) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const match = cookieString.match(new RegExp(`(?:^|;\\s*)${escapeRegExp(this.expiryCookieName)}=([^;]+)`));
|
|
176
|
+
if (!match) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
// Stored as Unix *seconds* (matching the FusionAuth SDK's own parser);
|
|
180
|
+
// callers compare against Date.now(), so normalise to milliseconds.
|
|
181
|
+
const seconds = parseInt(decodeURIComponent(match[1]), 10);
|
|
182
|
+
return Number.isFinite(seconds) ? seconds * 1000 : null;
|
|
183
|
+
}
|
|
184
|
+
readCookieString() {
|
|
185
|
+
if (this.cookieReader) {
|
|
186
|
+
return this.cookieReader();
|
|
187
|
+
}
|
|
188
|
+
if (typeof document === "undefined") {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
return document.cookie;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function escapeRegExp(value) {
|
|
195
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
196
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AuthProfile } from "./auth-profile.js";
|
|
2
|
+
import type { AuthProfileStore } from "./auth-store.js";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class shared by cookie and token auth strategies.
|
|
5
|
+
*
|
|
6
|
+
* Every client (`RestClient`, `GatewayClient`, `DooverDataProvider`) holds a
|
|
7
|
+
* reference to one `DooverAuth` instance so that refreshed tokens propagate
|
|
8
|
+
* everywhere automatically.
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class DooverAuth {
|
|
11
|
+
protected profile: AuthProfile | null;
|
|
12
|
+
protected configManager: AuthProfileStore | null;
|
|
13
|
+
/** Headers to merge into every outgoing HTTP request. */
|
|
14
|
+
abstract getHttpHeaders(): Promise<Record<string, string>>;
|
|
15
|
+
/** The `credentials` value for `fetch()`. */
|
|
16
|
+
abstract getFetchCredentials(): RequestCredentials;
|
|
17
|
+
/**
|
|
18
|
+
* Prepare websocket connection parameters.
|
|
19
|
+
*
|
|
20
|
+
* @param url The base websocket URL.
|
|
21
|
+
* @param canUseHeaders `true` when a `webSocketFactory` that supports
|
|
22
|
+
* custom headers is available.
|
|
23
|
+
* @returns An object with the (possibly modified) URL and optional headers.
|
|
24
|
+
*/
|
|
25
|
+
abstract prepareWebSocket(url: string, canUseHeaders: boolean): Promise<{
|
|
26
|
+
url: string;
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Imperatively set or clear the current access token.
|
|
31
|
+
* Subclasses that do not use tokens may no-op.
|
|
32
|
+
*/
|
|
33
|
+
abstract setToken(token: string | null, tokenExpires?: Date | number | null): void;
|
|
34
|
+
/**
|
|
35
|
+
* Imperatively set or clear the refresh token. Subclasses that do not use
|
|
36
|
+
* refresh tokens may no-op.
|
|
37
|
+
*/
|
|
38
|
+
abstract setRefreshToken(refreshToken: string | null): void;
|
|
39
|
+
/**
|
|
40
|
+
* Ensure the auth layer is ready (e.g. token refreshed if needed).
|
|
41
|
+
* Called before every HTTP request and before opening a websocket.
|
|
42
|
+
*/
|
|
43
|
+
abstract ensureReady(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Called after an authenticated HTTP request receives a 401. Return true when
|
|
46
|
+
* the auth layer recovered (for example by forcing a token refresh) and the
|
|
47
|
+
* request should be retried once.
|
|
48
|
+
*/
|
|
49
|
+
handleUnauthorized(): Promise<boolean>;
|
|
50
|
+
/** Attach a profile and optional config manager for refresh persistence. */
|
|
51
|
+
attachProfile(profile: AuthProfile, configManager?: AuthProfileStore): void;
|
|
52
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class shared by cookie and token auth strategies.
|
|
3
|
+
*
|
|
4
|
+
* Every client (`RestClient`, `GatewayClient`, `DooverDataProvider`) holds a
|
|
5
|
+
* reference to one `DooverAuth` instance so that refreshed tokens propagate
|
|
6
|
+
* everywhere automatically.
|
|
7
|
+
*/
|
|
8
|
+
export class DooverAuth {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.profile = null;
|
|
11
|
+
this.configManager = null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Called after an authenticated HTTP request receives a 401. Return true when
|
|
15
|
+
* the auth layer recovered (for example by forcing a token refresh) and the
|
|
16
|
+
* request should be retried once.
|
|
17
|
+
*/
|
|
18
|
+
async handleUnauthorized() {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
/** Attach a profile and optional config manager for refresh persistence. */
|
|
22
|
+
attachProfile(profile, configManager) {
|
|
23
|
+
this.profile = profile;
|
|
24
|
+
if (configManager) {
|
|
25
|
+
this.configManager = configManager;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
import type { AuthProfile } from "./auth-profile.js";
|
|
3
|
+
import type { AuthProfileStore } from "./auth-store.js";
|
|
4
|
+
export declare class DooverTokenAuth extends DooverAuth {
|
|
5
|
+
private token;
|
|
6
|
+
private tokenExpires;
|
|
7
|
+
private refreshToken;
|
|
8
|
+
private refreshTokenId;
|
|
9
|
+
private authServerUrl;
|
|
10
|
+
private authServerClientId;
|
|
11
|
+
private fetchImpl;
|
|
12
|
+
private refreshInFlight;
|
|
13
|
+
private authInvalid;
|
|
14
|
+
constructor(options: {
|
|
15
|
+
token?: string | null;
|
|
16
|
+
tokenExpires?: Date | number | null;
|
|
17
|
+
refreshToken?: string | null;
|
|
18
|
+
refreshTokenId?: string | null;
|
|
19
|
+
authServerUrl?: string | null;
|
|
20
|
+
authServerClientId?: string | null;
|
|
21
|
+
fetchImpl?: typeof fetch;
|
|
22
|
+
});
|
|
23
|
+
getHttpHeaders(): Promise<Record<string, string>>;
|
|
24
|
+
getFetchCredentials(): RequestCredentials;
|
|
25
|
+
prepareWebSocket(url: string, canUseHeaders: boolean): Promise<{
|
|
26
|
+
url: string;
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
}>;
|
|
29
|
+
setToken(token: string | null, tokenExpires?: Date | number | null): void;
|
|
30
|
+
setRefreshToken(refreshToken: string | null): void;
|
|
31
|
+
ensureReady(): Promise<void>;
|
|
32
|
+
handleUnauthorized(): Promise<boolean>;
|
|
33
|
+
attachProfile(profile: AuthProfile, configManager?: AuthProfileStore): void;
|
|
34
|
+
private needsRefresh;
|
|
35
|
+
private refresh;
|
|
36
|
+
private persistToProfile;
|
|
37
|
+
private markAuthInvalid;
|
|
38
|
+
private resolveExpiry;
|
|
39
|
+
}
|