@fluixi/oauth2 1.0.0-alpha.1 → 1.0.0-alpha.100
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 +1 -1
- package/dist/backchannel.cjs +462 -0
- package/dist/backchannel.d.ts +39 -0
- package/dist/backchannel.d.ts.map +1 -0
- package/dist/backchannel.js +97 -0
- package/dist/backchannel.mjs +307 -0
- package/dist/{browser-ONMHX3Z3.mjs → browser-TV25RBLT.mjs} +2 -2
- package/dist/browser.cjs +10 -3
- package/dist/browser.mjs +10 -3
- package/dist/callback.cjs +8 -7
- package/dist/callback.js +1 -1
- package/dist/callback.mjs +3 -2
- package/dist/{chunk-4NSOGPLM.mjs → chunk-2B3I72DV.mjs} +1 -1
- package/dist/chunk-KOP5Z4LB.mjs +108 -0
- package/dist/{chunk-25WE6UWI.mjs → chunk-KTGVSZE6.mjs} +1 -1
- package/dist/discovery.cjs +6 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +6 -1
- package/dist/discovery.mjs +6 -1
- package/dist/dpop-O3HWR7AH.mjs +22 -0
- package/dist/{dpop-LVPWWADA.mjs → dpop-SGWG3K2I.mjs} +26 -6
- package/dist/{dpop-NS7NKOWM.mjs → dpop-YPGCGL7S.mjs} +22 -2
- package/dist/dpop-store.cjs +4 -2
- package/dist/dpop-store.mjs +4 -2
- package/dist/dpop.cjs +22 -2
- package/dist/dpop.d.ts +18 -1
- package/dist/dpop.d.ts.map +1 -1
- package/dist/dpop.js +23 -2
- package/dist/dpop.mjs +22 -2
- package/dist/index.cjs +135 -10
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.mjs +138 -13
- package/dist/module.cjs +44 -0
- package/dist/module.d.ts +13 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +22 -0
- package/dist/module.mjs +23 -0
- package/dist/server.cjs +755 -80
- package/dist/server.d.ts +91 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +518 -65
- package/dist/server.mjs +638 -82
- package/dist/service-client.cjs +7 -2
- package/dist/service-client.mjs +9 -4
- package/dist/service.cjs +116 -7
- package/dist/service.d.ts +2 -18
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +48 -5
- package/dist/service.mjs +116 -7
- package/dist/session-monitor.cjs +98 -0
- package/dist/session-monitor.d.ts +32 -0
- package/dist/session-monitor.d.ts.map +1 -0
- package/dist/session-monitor.js +104 -0
- package/dist/session-monitor.mjs +77 -0
- package/dist/tokens.cjs +1 -1
- package/dist/tokens.d.ts +2 -2
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +1 -1
- package/dist/tokens.mjs +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/types.d.ts +12 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -12
- package/dist/verify.cjs +30 -4
- package/dist/verify.mjs +12 -7
- package/package.json +22 -16
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
/*! @fluixi/oauth2 v1.0.0-alpha.
|
|
2
|
-
import "./chunk-
|
|
1
|
+
/*! @fluixi/oauth2 v1.0.0-alpha.100 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
import "./chunk-KTGVSZE6.mjs";
|
|
3
3
|
|
|
4
4
|
// src/service.ts
|
|
5
|
+
import { createSignal, markReactiveScope, openReactiveScope, withReactiveScope } from "@fluixi/reactive/signal";
|
|
5
6
|
import { createSession } from "@fluixi/session";
|
|
6
7
|
import { createAuthHooks } from "@fluixi/auth/client";
|
|
7
8
|
|
|
@@ -111,7 +112,7 @@ function resolveMethod(auth) {
|
|
|
111
112
|
}
|
|
112
113
|
async function loadJose() {
|
|
113
114
|
try {
|
|
114
|
-
return await import("./browser-
|
|
115
|
+
return await import("./browser-TV25RBLT.mjs");
|
|
115
116
|
} catch {
|
|
116
117
|
throw new OAuthError(
|
|
117
118
|
"private_key_jwt needs `jose`. Install it: npm i jose. It is an optional peer, so a client using a secret does not carry it.",
|
|
@@ -151,7 +152,7 @@ async function applyClientAuth(auth, endpoint, headers, form) {
|
|
|
151
152
|
// src/dpop.ts
|
|
152
153
|
async function loadJose2() {
|
|
153
154
|
try {
|
|
154
|
-
return await import("./browser-
|
|
155
|
+
return await import("./browser-TV25RBLT.mjs");
|
|
155
156
|
} catch {
|
|
156
157
|
throw new OAuthError(
|
|
157
158
|
"DPoP needs `jose`. Install it: npm i jose. It is an optional peer, so a client not using DPoP does not carry it.",
|
|
@@ -159,9 +160,11 @@ async function loadJose2() {
|
|
|
159
160
|
);
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
async function createDpopKey(alg = "ES256") {
|
|
163
|
+
async function createDpopKey(alg = "ES256", options = {}) {
|
|
163
164
|
const jose = await loadJose2();
|
|
164
|
-
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
165
|
+
const { privateKey, publicKey } = await jose.generateKeyPair(alg, {
|
|
166
|
+
extractable: options.extractable ?? false
|
|
167
|
+
});
|
|
165
168
|
const publicJwk = { ...await jose.exportJWK(publicKey) };
|
|
166
169
|
return {
|
|
167
170
|
privateKey,
|
|
@@ -307,8 +310,12 @@ async function discover(issuer, fetcher = fetch) {
|
|
|
307
310
|
try {
|
|
308
311
|
response = await fetcher(documentUrl(issuer));
|
|
309
312
|
} catch (cause) {
|
|
313
|
+
const why = cause instanceof Error ? cause.message : String(cause);
|
|
310
314
|
throw new OAuthError(
|
|
311
|
-
|
|
315
|
+
typeof window === "undefined" ? (
|
|
316
|
+
// On a server nothing blocks the read: the provider is down, or the address is wrong.
|
|
317
|
+
`Could not reach the provider at ${documentUrl(issuer)}: is it running, and is the issuer right? (${why})`
|
|
318
|
+
) : `Could not read the discovery document at ${documentUrl(issuer)}. In a browser this is usually the provider refusing a cross-origin read: give \`endpoints\` directly, or resolve them on a server. (${why})`,
|
|
312
319
|
"discovery_unreachable"
|
|
313
320
|
);
|
|
314
321
|
}
|
|
@@ -333,6 +340,7 @@ async function discover(issuer, fetcher = fetch) {
|
|
|
333
340
|
jwks: doc.jwks_uri,
|
|
334
341
|
introspection: doc.introspection_endpoint,
|
|
335
342
|
revocation: doc.revocation_endpoint,
|
|
343
|
+
checkSession: doc.check_session_iframe,
|
|
336
344
|
issuer: doc.issuer ?? issuer
|
|
337
345
|
};
|
|
338
346
|
})();
|
|
@@ -791,6 +799,81 @@ function createServerClient(config, fetcher = fetch) {
|
|
|
791
799
|
};
|
|
792
800
|
}
|
|
793
801
|
|
|
802
|
+
// src/session-monitor.ts
|
|
803
|
+
var SETTLE_MS = 15e3;
|
|
804
|
+
var GUARD_KEY = "fx-session-check";
|
|
805
|
+
function recentlyActed() {
|
|
806
|
+
try {
|
|
807
|
+
return Date.now() - Number(sessionStorage.getItem(GUARD_KEY) ?? 0) < SETTLE_MS;
|
|
808
|
+
} catch {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
function markActed() {
|
|
813
|
+
try {
|
|
814
|
+
sessionStorage.setItem(GUARD_KEY, String(Date.now()));
|
|
815
|
+
} catch {
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function watchProviderSession(options = {}) {
|
|
819
|
+
if (typeof window === "undefined" || typeof document === "undefined") return () => {
|
|
820
|
+
};
|
|
821
|
+
const base = (options.basePath ?? "/auth").replace(/\/$/, "");
|
|
822
|
+
const fetcher = options.fetcher ?? fetch;
|
|
823
|
+
const onChange = options.onChange ?? (() => {
|
|
824
|
+
const login = new URLSearchParams({ prompt: "none", returnTo: location.pathname + location.search });
|
|
825
|
+
location.assign(`${base}/login?${login}`);
|
|
826
|
+
});
|
|
827
|
+
let stopped = false;
|
|
828
|
+
const cleanups = [];
|
|
829
|
+
const stop = () => {
|
|
830
|
+
stopped = true;
|
|
831
|
+
for (const cleanup of cleanups.splice(0)) cleanup();
|
|
832
|
+
};
|
|
833
|
+
void (async () => {
|
|
834
|
+
const check = await fetcher(`${base}/session-check`, { credentials: "same-origin" }).then((response) => response.ok ? response.json() : null).catch(() => null);
|
|
835
|
+
if (stopped || !check?.frame || !check.state) return;
|
|
836
|
+
const origin = new URL(check.frame).origin;
|
|
837
|
+
const frame = document.createElement("iframe");
|
|
838
|
+
frame.src = check.frame;
|
|
839
|
+
frame.title = "session check";
|
|
840
|
+
frame.setAttribute("aria-hidden", "true");
|
|
841
|
+
frame.tabIndex = -1;
|
|
842
|
+
frame.style.cssText = "position:absolute;width:0;height:0;border:0;visibility:hidden";
|
|
843
|
+
const message = `${check.clientId} ${check.state}`;
|
|
844
|
+
const ask = () => {
|
|
845
|
+
if (!stopped && document.visibilityState === "visible") frame.contentWindow?.postMessage(message, origin);
|
|
846
|
+
};
|
|
847
|
+
let confirmed = false;
|
|
848
|
+
const answer = (event) => {
|
|
849
|
+
if (event.origin !== origin || event.source !== frame.contentWindow) return;
|
|
850
|
+
if (event.data === "unchanged") confirmed = true;
|
|
851
|
+
else if (event.data === "changed") {
|
|
852
|
+
stop();
|
|
853
|
+
if (!confirmed && recentlyActed()) return;
|
|
854
|
+
markActed();
|
|
855
|
+
onChange();
|
|
856
|
+
} else if (event.data === "error") {
|
|
857
|
+
stop();
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
window.addEventListener("message", answer);
|
|
861
|
+
frame.addEventListener("load", ask);
|
|
862
|
+
document.addEventListener("visibilitychange", ask);
|
|
863
|
+
window.addEventListener("focus", ask);
|
|
864
|
+
const timer = setInterval(ask, options.intervalMs ?? 3e3);
|
|
865
|
+
document.body.appendChild(frame);
|
|
866
|
+
cleanups.push(() => {
|
|
867
|
+
window.removeEventListener("message", answer);
|
|
868
|
+
document.removeEventListener("visibilitychange", ask);
|
|
869
|
+
window.removeEventListener("focus", ask);
|
|
870
|
+
clearInterval(timer);
|
|
871
|
+
frame.remove();
|
|
872
|
+
});
|
|
873
|
+
})();
|
|
874
|
+
return stop;
|
|
875
|
+
}
|
|
876
|
+
|
|
794
877
|
// src/service.ts
|
|
795
878
|
function paramsFromUrl(url) {
|
|
796
879
|
const href = url ?? (typeof location === "undefined" ? null : location.href);
|
|
@@ -808,18 +891,28 @@ function clientFor(options) {
|
|
|
808
891
|
return options.config.tokens === "server" ? createServerClient(options.config) : createBrowserClient(options.config);
|
|
809
892
|
}
|
|
810
893
|
function createAuthService(options) {
|
|
894
|
+
const tokens = options.config.tokens;
|
|
895
|
+
const scope = openReactiveScope({ kind: "service", name: "AuthService", ...tokens ? { detail: `tokens: ${tokens}` } : {} });
|
|
896
|
+
const service = withReactiveScope(scope, () => buildAuthService(options));
|
|
897
|
+
markReactiveScope(service, scope);
|
|
898
|
+
return service;
|
|
899
|
+
}
|
|
900
|
+
function buildAuthService(options) {
|
|
811
901
|
const client = clientFor(options);
|
|
812
902
|
let latest = null;
|
|
903
|
+
const fetchUserFor = async (token) => {
|
|
904
|
+
if (options.fetchUser) return options.fetchUser(token);
|
|
905
|
+
return client.fetchUser(token === COOKIE_SESSION ? void 0 : token);
|
|
906
|
+
};
|
|
907
|
+
const resumesFromCookie = options.config.tokens === "server" && typeof window !== "undefined";
|
|
908
|
+
const [ready, setReady] = createSignal(!resumesFromCookie);
|
|
813
909
|
const session = createSession({
|
|
814
910
|
/** The credential is the callback, so this is the code exchange. */
|
|
815
911
|
async login(params) {
|
|
816
912
|
latest = await client.handleCallback(params);
|
|
817
913
|
return { token: latest.accessToken, expiresAt: latest.expiresAt };
|
|
818
914
|
},
|
|
819
|
-
|
|
820
|
-
if (options.fetchUser) return options.fetchUser(token);
|
|
821
|
-
return client.fetchUser(token === COOKIE_SESSION ? void 0 : token);
|
|
822
|
-
},
|
|
915
|
+
fetchUser: fetchUserFor,
|
|
823
916
|
async refresh() {
|
|
824
917
|
latest = await client.refresh();
|
|
825
918
|
return { token: latest.accessToken, expiresAt: latest.expiresAt };
|
|
@@ -842,11 +935,27 @@ function createAuthService(options) {
|
|
|
842
935
|
});
|
|
843
936
|
const hooks = createAuthHooks({
|
|
844
937
|
session,
|
|
938
|
+
ready,
|
|
845
939
|
navigate: options.navigate,
|
|
846
940
|
loginPath: options.loginPath ?? "/login",
|
|
847
941
|
homePath: options.homePath ?? "/",
|
|
848
942
|
forbiddenPath: options.forbiddenPath ?? "/403"
|
|
849
943
|
});
|
|
944
|
+
if (resumesFromCookie && options.config.tokens === "server" && options.config.watchSession !== false) {
|
|
945
|
+
watchProviderSession({ basePath: options.config.basePath });
|
|
946
|
+
}
|
|
947
|
+
const renderedSignedOut = hooks.store.seeded && hooks.store.value().user == null;
|
|
948
|
+
if (resumesFromCookie && renderedSignedOut) setReady(true);
|
|
949
|
+
else if (resumesFromCookie) {
|
|
950
|
+
void (async () => {
|
|
951
|
+
try {
|
|
952
|
+
await session.adopt(COOKIE_SESSION, await fetchUserFor(COOKIE_SESSION));
|
|
953
|
+
} catch {
|
|
954
|
+
} finally {
|
|
955
|
+
setReady(true);
|
|
956
|
+
}
|
|
957
|
+
})();
|
|
958
|
+
}
|
|
850
959
|
return Object.assign(session, {
|
|
851
960
|
client,
|
|
852
961
|
protectedRoute: hooks.protectedRoute,
|
|
@@ -882,14 +991,29 @@ function createAuthService(options) {
|
|
|
882
991
|
}
|
|
883
992
|
|
|
884
993
|
// src/tokens.ts
|
|
885
|
-
import { injectionToken } from "@fluixi/
|
|
994
|
+
import { injectionToken } from "@fluixi/di";
|
|
886
995
|
var AuthServiceToken = injectionToken("AuthService");
|
|
887
996
|
var AuthClientToken = injectionToken("AuthClient");
|
|
997
|
+
|
|
998
|
+
// src/module.ts
|
|
999
|
+
import { defineModule } from "@fluixi/start/app";
|
|
1000
|
+
function authModule(auth) {
|
|
1001
|
+
return defineModule({
|
|
1002
|
+
name: "oauth2",
|
|
1003
|
+
providers: [
|
|
1004
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
1005
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
1006
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
1007
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
1008
|
+
]
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
888
1011
|
export {
|
|
889
1012
|
AuthClientToken,
|
|
890
1013
|
AuthServiceToken,
|
|
891
1014
|
COOKIE_SESSION,
|
|
892
1015
|
OAuthError,
|
|
1016
|
+
authModule,
|
|
893
1017
|
boundKeyOf,
|
|
894
1018
|
clearDiscoveryCache,
|
|
895
1019
|
createAuthService,
|
|
@@ -905,5 +1029,6 @@ export {
|
|
|
905
1029
|
paramsFromUrl,
|
|
906
1030
|
proofFor,
|
|
907
1031
|
safeReturnTo,
|
|
908
|
-
thumbprintOf
|
|
1032
|
+
thumbprintOf,
|
|
1033
|
+
watchProviderSession
|
|
909
1034
|
};
|
package/dist/module.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/module.ts
|
|
21
|
+
var module_exports = {};
|
|
22
|
+
__export(module_exports, {
|
|
23
|
+
authModule: () => authModule
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(module_exports);
|
|
26
|
+
var import_app = require("@fluixi/start/app");
|
|
27
|
+
|
|
28
|
+
// src/tokens.ts
|
|
29
|
+
var import_di = require("@fluixi/di");
|
|
30
|
+
var AuthServiceToken = (0, import_di.injectionToken)("AuthService");
|
|
31
|
+
var AuthClientToken = (0, import_di.injectionToken)("AuthClient");
|
|
32
|
+
|
|
33
|
+
// src/module.ts
|
|
34
|
+
function authModule(auth) {
|
|
35
|
+
return (0, import_app.defineModule)({
|
|
36
|
+
name: "oauth2",
|
|
37
|
+
providers: [
|
|
38
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
39
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
40
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
41
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-module half of this package, listed in `src/app.config.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Registers the app's service under `AuthServiceToken` and its client under
|
|
5
|
+
* `AuthClientToken` on both sides. Package code reaches the service through those tokens,
|
|
6
|
+
* `OAuthCallback` among it, because a package cannot import the app. The server half, the
|
|
7
|
+
* routes and session middleware of `tokens: 'server'`, is `authServerModule` in
|
|
8
|
+
* `@fluixi/oauth2/server`, for `app.config.server.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { type AppModule } from '@fluixi/start/app';
|
|
11
|
+
import type { AuthService } from './service.js';
|
|
12
|
+
export declare function authModule<U, P, Q>(auth: AuthService<U, P, Q>): AppModule;
|
|
13
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAUzE"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-module half of this package, listed in `src/app.config.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Registers the app's service under `AuthServiceToken` and its client under
|
|
5
|
+
* `AuthClientToken` on both sides. Package code reaches the service through those tokens,
|
|
6
|
+
* `OAuthCallback` among it, because a package cannot import the app. The server half, the
|
|
7
|
+
* routes and session middleware of `tokens: 'server'`, is `authServerModule` in
|
|
8
|
+
* `@fluixi/oauth2/server`, for `app.config.server.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { defineModule } from '@fluixi/start/app';
|
|
11
|
+
import { AuthServiceToken, AuthClientToken } from './tokens.js';
|
|
12
|
+
export function authModule(auth) {
|
|
13
|
+
return defineModule({
|
|
14
|
+
name: 'oauth2',
|
|
15
|
+
providers: [
|
|
16
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
17
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
18
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
19
|
+
{ provide: AuthClientToken, useValue: auth.client },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
}
|
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/module.ts
|
|
2
|
+
import { defineModule } from "@fluixi/start/app";
|
|
3
|
+
|
|
4
|
+
// src/tokens.ts
|
|
5
|
+
import { injectionToken } from "@fluixi/di";
|
|
6
|
+
var AuthServiceToken = injectionToken("AuthService");
|
|
7
|
+
var AuthClientToken = injectionToken("AuthClient");
|
|
8
|
+
|
|
9
|
+
// src/module.ts
|
|
10
|
+
function authModule(auth) {
|
|
11
|
+
return defineModule({
|
|
12
|
+
name: "oauth2",
|
|
13
|
+
providers: [
|
|
14
|
+
// One instance for every request on the server. It holds no per-visitor state there:
|
|
15
|
+
// the signed-in user comes from request locals, which `sessionLocals` fills per request.
|
|
16
|
+
{ provide: AuthServiceToken, useValue: auth },
|
|
17
|
+
{ provide: AuthClientToken, useValue: auth.client }
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
authModule
|
|
23
|
+
};
|