@logto/remix 1.0.0-beta.9

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Silverhand
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # Logto Remix SDK
2
+ [![Version](https://img.shields.io/npm/v/@logto/remix)](https://www.npmjs.com/package/@logto/remix)
3
+ [![Build Status](https://github.com/logto-io/js/actions/workflows/main.yml/badge.svg)](https://github.com/logto-io/js/actions/workflows/main.yml)
4
+ [![Codecov](https://img.shields.io/codecov/c/github/logto-io/js)](https://app.codecov.io/gh/logto-io/js?branch=master)
5
+
6
+ The Logto Remix SDK written in TypeScript.
7
+
8
+ ## Installation
9
+
10
+ ### Using npm
11
+
12
+ ```bash
13
+ npm install @logto/remix
14
+ ```
15
+
16
+ ### Using yarn
17
+
18
+ ```bash
19
+ yarn add @logto/remix
20
+ ```
21
+
22
+ ### Using pnpm
23
+
24
+ ```bash
25
+ pnpm add @logto/remix
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ Before initializing the SDK, we have to create a `SessionStorage` instance which takes care of the session persistence. In our case, we want to use a cookie-based session:
31
+
32
+ ```ts
33
+ // services/authentication.ts
34
+ import { createCookieSessionStorage } from "@remix-run/node";
35
+
36
+ const sessionStorage = createCookieSessionStorage({
37
+ cookie: {
38
+ name: "logto-session",
39
+ maxAge: 14 * 24 * 60 * 60,
40
+ secrets: ["s3cret1"],
41
+ },
42
+ });
43
+ ```
44
+
45
+ Afterwards, we can initialize the SDK via:
46
+
47
+ ```ts
48
+ // app/services/authentication.ts
49
+
50
+ import { makeLogtoRemix } from "@logto/remix";
51
+
52
+ export const logto = makeLogtoRemix(
53
+ {
54
+ endpoint: process.env.LOGTO_ENDPOINT!,
55
+ appId: process.env.LOGTO_APP_ID!,
56
+ appSecret: process.env.LOGTO_APP_SECRET!,
57
+ baseUrl: process.env.LOGTO_BASE_URL!,
58
+ },
59
+ { sessionStorage }
60
+ );
61
+ ```
62
+
63
+ Whereas the environment variables reflect the respective configuration of the application in Logto.
64
+
65
+ ### Mounting the authentication route handlers
66
+
67
+ The SDK ships with a convenient function that mounts the authentication routes: sign-in, sign-in callback and the sign-out route:
68
+
69
+ ```ts
70
+ // app/routes/api/logto/$action.ts
71
+
72
+ import { logto } from "../../../services/authentication";
73
+
74
+ export const loader = logto.handleAuthRoutes({
75
+ "sign-in": {
76
+ path: "/api/logto/sign-in",
77
+ redirectBackTo: "/api/logto/callback",
78
+ },
79
+ "sign-in-callback": {
80
+ path: "/api/logto/callback",
81
+ redirectBackTo: "/",
82
+ },
83
+ "sign-out": {
84
+ path: "/api/logto/sign-out",
85
+ redirectBackTo: "/",
86
+ },
87
+ });
88
+ ```
89
+
90
+ As you can see, the mount process is configurable and you can adjust it for your particular route structure. The whole URL path structure can be customized via the passed configuration object.
91
+
92
+ When mounting the routes as described above, you can navigate your browser to `/api/logto/sign-in` and you should be redirected to your Logto instance where you have to authenticate then.
93
+
94
+ ### Get the authentication context
95
+
96
+ A typical use case is to fetch the _authentication context_ which contains information about the respective user. With that information, it is possible to decide if the user is authenticated or not. The SDK exposes a function that can be used in a Remix `loader` function:
97
+
98
+ ```ts
99
+ // app/routes/index.tsx
100
+ import type { LogtoContext } from "@openformation/logto-remix";
101
+ import { LoaderFunction, json } from "@remix-run/node";
102
+ import { useLoaderData } from "@remix-run/react";
103
+
104
+ import { logto } from "~/services/authentication";
105
+
106
+ type LoaderResponse = {
107
+ readonly context: LogtoContext;
108
+ };
109
+
110
+ export const loader: LoaderFunction = async ({ request }) => {
111
+ const context = await logto.getContext({ includeAccessToken: false })(
112
+ request
113
+ );
114
+
115
+ if (!context.isAuthenticated) {
116
+ return redirect("/api/logto/sign-in");
117
+ }
118
+
119
+ return json<LoaderResponse>({ context });
120
+ };
121
+
122
+ const Home = () => {
123
+ const data = useLoaderData<LoaderResponse>();
124
+
125
+ return <div>Protected Route.</div>;
126
+ };
127
+ ```
128
+
129
+ ## Resources
130
+
131
+ [![Website](https://img.shields.io/badge/website-logto.io-8262F8.svg)](https://logto.io/)
132
+ [![Discord](https://img.shields.io/discord/965845662535147551?logo=discord&logoColor=ffffff&color=7389D8&cacheSeconds=600)](https://discord.gg/UEPaF3j5e6)
package/lib/index.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { LogtoConfig } from "@logto/node";
2
+ import { SessionStorage } from "@remix-run/node";
3
+ export { type LogtoConfig } from '@logto/node';
4
+ export { type LogtoContext } from '@logto/node';
5
+ type Config = Readonly<LogtoConfig> & {
6
+ readonly baseUrl: string;
7
+ };
8
+ export const makeLogtoRemix: (config: Config, deps: {
9
+ sessionStorage: SessionStorage;
10
+ }) => Readonly<{
11
+ handleAuthRoutes: (dto: {
12
+ "sign-in": {
13
+ readonly path: string;
14
+ readonly redirectBackTo: string;
15
+ };
16
+ "sign-in-callback": {
17
+ readonly path: string;
18
+ readonly redirectBackTo: string;
19
+ };
20
+ "sign-out": {
21
+ readonly path: string;
22
+ readonly redirectBackTo: string;
23
+ };
24
+ }) => import("@remix-run/node").LoaderFunction;
25
+ getContext: (dto: {
26
+ includeAccessToken: boolean;
27
+ }) => (request: Request) => Promise<import("@logto/node").LogtoContext>;
28
+ }>;
29
+ export { type LogtoContext } from '@logto/node';
30
+
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";;ACeA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AKW/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AkBnBhD,cAAc,QAAQ,CAAC,WAAW,CAAC,GAAG;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,OAAO,MAAM,yBACH,MAAM,QACR;IACJ,gBAAgB,cAAc,CAAC;CAChC;;;;;;;;;;;;;;;sBAemB;QAAE,kBAAkB,EAAE,OAAO,CAAA;KAAE;EAMpD,CAAC;AAEF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC","sources":["packages/remix/src/src/infrastructure/logto/create-storage.ts","packages/remix/src/src/infrastructure/logto/create-client.ts","packages/remix/src/src/infrastructure/logto/get-context.ts","packages/remix/src/src/infrastructure/logto/handle-sign-in.ts","packages/remix/src/src/infrastructure/logto/handle-sign-in-callback.ts","packages/remix/src/src/infrastructure/logto/handle-sign-out.ts","packages/remix/src/src/infrastructure/logto/index.ts","packages/remix/src/src/framework/get-cookie-header-from-request.ts","packages/remix/src/src/useCases/getContext/GetContextUseCase.ts","packages/remix/src/src/useCases/getContext/GetContextController.ts","packages/remix/src/src/useCases/getContext/index.ts","packages/remix/src/src/useCases/handleSignIn/HandleSignInUseCase.ts","packages/remix/src/src/useCases/handleSignIn/HandleSignInController.ts","packages/remix/src/src/useCases/handleSignIn/index.ts","packages/remix/src/src/useCases/handleSignInCallback/HandleSignInCallbackError.ts","packages/remix/src/src/useCases/handleSignInCallback/HandleSignInCallbackUseCase.ts","packages/remix/src/src/useCases/handleSignInCallback/HandleSignInCallbackController.ts","packages/remix/src/src/useCases/handleSignInCallback/index.ts","packages/remix/src/src/useCases/handleSignOut/HandleSignOutError.ts","packages/remix/src/src/useCases/handleSignOut/HandleSignOutUseCase.ts","packages/remix/src/src/useCases/handleSignOut/HandleSignOutController.ts","packages/remix/src/src/useCases/handleSignOut/index.ts","packages/remix/src/src/useCases/handleAuthRoutes/HandleAuthRoutesError.ts","packages/remix/src/src/useCases/handleAuthRoutes/index.ts","packages/remix/src/src/index.ts","packages/remix/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import { LogtoConfig } from '@logto/node';\nimport { SessionStorage } from '@remix-run/node';\n\nimport { makeLogtoAdapter } from './infrastructure/logto';\nimport { makeGetContext } from './useCases/getContext';\nimport { makeHandleAuthRoutes } from './useCases/handleAuthRoutes';\n\ntype Config = Readonly<LogtoConfig> & {\n readonly baseUrl: string;\n};\n\nexport const makeLogtoRemix = (\n config: Config,\n deps: {\n sessionStorage: SessionStorage;\n }\n) => {\n const { sessionStorage } = deps;\n\n const { baseUrl } = config;\n\n const createLogtoAdapter = makeLogtoAdapter(config);\n\n return Object.freeze({\n handleAuthRoutes: makeHandleAuthRoutes({\n baseUrl,\n createLogtoAdapter,\n sessionStorage,\n }),\n\n getContext: (dto: { includeAccessToken: boolean }) =>\n makeGetContext(dto, {\n createLogtoAdapter,\n sessionStorage,\n }),\n });\n};\n\nexport { type LogtoContext } from '@logto/node';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/lib/index.js ADDED
@@ -0,0 +1,494 @@
1
+ var $jCOgx$logtonode = require("@logto/node");
2
+ var $jCOgx$remixrunnode = require("@remix-run/node");
3
+
4
+ function $parcel$export(e, n, v, s) {
5
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
6
+ }
7
+ function $parcel$interopDefault(a) {
8
+ return a && a.__esModule ? a.default : a;
9
+ }
10
+
11
+ $parcel$export(module.exports, "makeLogtoRemix", () => $0ca379f5bbbb8613$export$502a4d54d411a9fd);
12
+
13
+ const $94c40b1de01e2ef7$export$60d790dda55ffee6 = (config, storage)=>// Have to deactivate the eslint rule here as the `LogtoClient`
14
+ // awaits a `navigate` function.
15
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
16
+ (navigate = ()=>{})=>{
17
+ return new (0, ($parcel$interopDefault($jCOgx$logtonode)))(config, {
18
+ storage: storage,
19
+ navigate: navigate
20
+ });
21
+ };
22
+
23
+
24
+ class $827429ca01feafa0$var$LogtoStorage {
25
+ static fromSession = (session)=>{
26
+ return new $827429ca01feafa0$var$LogtoStorage({
27
+ session: session
28
+ });
29
+ };
30
+ constructor(properties){
31
+ this.properties = properties;
32
+ this.session = this.properties.session;
33
+ this.setItem = async (key, value)=>{
34
+ this.session.set(key, value);
35
+ };
36
+ this.getItem = async (key)=>{
37
+ const itemExists = this.session.has(key);
38
+ if (!itemExists) return null;
39
+ return String(this.session.get(key));
40
+ };
41
+ this.removeItem = async (key)=>{
42
+ this.session.unset(key);
43
+ };
44
+ this.save = async ()=>{
45
+ // Not required as the persistence happens in the integration layer
46
+ };
47
+ }
48
+ }
49
+ const $827429ca01feafa0$export$d184a47a971dd4b9 = (session)=>$827429ca01feafa0$var$LogtoStorage.fromSession(session);
50
+
51
+
52
+ const $929a552c463d8b64$export$f4d9bb4cf5d2b40c = (deps)=>async (request)=>{
53
+ const { storage: storage , createClient: createClient } = deps;
54
+ const client = createClient();
55
+ const context = await client.getContext(request.includeAccessToken);
56
+ return {
57
+ context: context
58
+ };
59
+ };
60
+
61
+
62
+ class $57de529bd46d1977$var$HandleSignInCommand {
63
+ static fromDependencies = (dependencies)=>new $57de529bd46d1977$var$HandleSignInCommand({
64
+ createClient: dependencies.createClient
65
+ });
66
+ constructor(properties){
67
+ this.properties = properties;
68
+ this.navigateToUrl = "/api/sign-in";
69
+ }
70
+ async execute(request) {
71
+ const { createClient: createClient } = this.properties;
72
+ const client = createClient((url)=>{
73
+ this.navigateToUrl = url;
74
+ });
75
+ await client.signIn(request.redirectUri);
76
+ return {
77
+ navigateToUrl: this.navigateToUrl
78
+ };
79
+ }
80
+ }
81
+ const $57de529bd46d1977$export$3c00ad1b716e9134 = (deps)=>async (request)=>{
82
+ const { storage: storage , createClient: createClient } = deps;
83
+ const command = $57de529bd46d1977$var$HandleSignInCommand.fromDependencies({
84
+ createClient: createClient
85
+ });
86
+ const { navigateToUrl: navigateToUrl } = await command.execute(request);
87
+ return {
88
+ session: storage.session,
89
+ navigateToUrl: navigateToUrl
90
+ };
91
+ };
92
+
93
+
94
+ const $a5a397d32fbbf55b$export$9c07365b51e93ba3 = (deps)=>async (request)=>{
95
+ const { storage: storage , createClient: createClient } = deps;
96
+ const client = createClient();
97
+ await client.handleSignInCallback(request.callbackUri);
98
+ return {
99
+ session: storage.session
100
+ };
101
+ };
102
+
103
+
104
+ class $43687e20c64eb0a9$var$HandleSignOutCommand {
105
+ static fromDependencies = (dependencies)=>new $43687e20c64eb0a9$var$HandleSignOutCommand({
106
+ createClient: dependencies.createClient
107
+ });
108
+ constructor(properties){
109
+ this.properties = properties;
110
+ this.navigateToUrl = "/api/sign-in";
111
+ }
112
+ async execute(request) {
113
+ const { createClient: createClient } = this.properties;
114
+ const client = createClient((url)=>{
115
+ this.navigateToUrl = url;
116
+ });
117
+ await client.signOut(request.redirectUri);
118
+ return {
119
+ navigateToUrl: this.navigateToUrl
120
+ };
121
+ }
122
+ }
123
+ const $43687e20c64eb0a9$export$89f18ff1488dade0 = (deps)=>async (request)=>{
124
+ const { createClient: createClient } = deps;
125
+ const command = $43687e20c64eb0a9$var$HandleSignOutCommand.fromDependencies({
126
+ createClient: createClient
127
+ });
128
+ return command.execute(request);
129
+ };
130
+
131
+
132
+ const $be51f08b006ed125$export$5e1ab578feca185a = (config)=>(session)=>{
133
+ const storage = (0, $827429ca01feafa0$export$d184a47a971dd4b9)(session);
134
+ const createClient = (0, $94c40b1de01e2ef7$export$60d790dda55ffee6)(config, storage);
135
+ return {
136
+ handleSignIn: (0, $57de529bd46d1977$export$3c00ad1b716e9134)({
137
+ storage: storage,
138
+ createClient: createClient
139
+ }),
140
+ handleSignInCallback: (0, $a5a397d32fbbf55b$export$9c07365b51e93ba3)({
141
+ storage: storage,
142
+ createClient: createClient
143
+ }),
144
+ handleSignOut: (0, $43687e20c64eb0a9$export$89f18ff1488dade0)({
145
+ createClient: createClient
146
+ }),
147
+ getContext: (0, $929a552c463d8b64$export$f4d9bb4cf5d2b40c)({
148
+ storage: storage,
149
+ createClient: createClient
150
+ })
151
+ };
152
+ };
153
+
154
+
155
+ const $978a582c6f8c8e7b$export$5c6fae4c79d686e4 = (request)=>request.headers.get("Cookie");
156
+
157
+
158
+ class $9d799c5e2ef306d6$export$32386402b3f0a45 {
159
+ static fromDto = (dto)=>new $9d799c5e2ef306d6$export$32386402b3f0a45({
160
+ useCase: dto.useCase,
161
+ includeAccessToken: dto.includeAccessToken ?? false
162
+ });
163
+ constructor(properties){
164
+ this.properties = properties;
165
+ this.useCase = this.properties.useCase;
166
+ this.includeAccessToken = this.properties.includeAccessToken;
167
+ this.execute = async (request)=>{
168
+ const cookieHeader = (0, $978a582c6f8c8e7b$export$5c6fae4c79d686e4)(request);
169
+ const { includeAccessToken: includeAccessToken } = this;
170
+ const result = await this.useCase({
171
+ cookieHeader: cookieHeader ?? undefined,
172
+ includeAccessToken: includeAccessToken
173
+ });
174
+ return result.context;
175
+ };
176
+ }
177
+ }
178
+
179
+
180
+ const $407324a9de7811e9$export$53ae38c062671653 = (deps)=>async (request)=>{
181
+ const { sessionStorage: sessionStorage , createLogtoAdapter: createLogtoAdapter } = deps;
182
+ const session = await sessionStorage.getSession(request.cookieHeader);
183
+ const logto = createLogtoAdapter(session);
184
+ const response = await logto.getContext({
185
+ includeAccessToken: request.includeAccessToken
186
+ });
187
+ return {
188
+ context: response.context
189
+ };
190
+ };
191
+
192
+
193
+ const $7b69d37f648a005c$export$f4d9bb4cf5d2b40c = (dto, deps)=>async (request)=>{
194
+ const { createLogtoAdapter: createLogtoAdapter , sessionStorage: sessionStorage } = deps;
195
+ const useCase = (0, $407324a9de7811e9$export$53ae38c062671653)({
196
+ createLogtoAdapter: createLogtoAdapter,
197
+ sessionStorage: sessionStorage
198
+ });
199
+ const controller = (0, $9d799c5e2ef306d6$export$32386402b3f0a45).fromDto({
200
+ useCase: useCase,
201
+ includeAccessToken: dto.includeAccessToken
202
+ });
203
+ return controller.execute(request);
204
+ };
205
+
206
+
207
+
208
+
209
+ class $6ca04f2e8ce3f248$export$8bb8370a824a554b {
210
+ static fromDto = (dto)=>new $6ca04f2e8ce3f248$export$8bb8370a824a554b({
211
+ useCase: dto.useCase,
212
+ redirectUri: dto.redirectUri
213
+ });
214
+ constructor(properties){
215
+ this.properties = properties;
216
+ this.useCase = this.properties.useCase;
217
+ this.redirectUri = this.properties.redirectUri;
218
+ this.execute = async (request)=>{
219
+ const cookieHeader = (0, $978a582c6f8c8e7b$export$5c6fae4c79d686e4)(request);
220
+ const { redirectUri: redirectUri } = this;
221
+ const result = await this.useCase({
222
+ cookieHeader: cookieHeader ?? undefined,
223
+ redirectUri: redirectUri
224
+ });
225
+ return (0, $jCOgx$remixrunnode.redirect)(result.navigateToUrl, {
226
+ headers: {
227
+ "Set-Cookie": result.cookieHeader
228
+ }
229
+ });
230
+ };
231
+ }
232
+ }
233
+
234
+
235
+ const $b3adef7963962600$export$463099392e1e6404 = (deps)=>async (request)=>{
236
+ const { sessionStorage: sessionStorage , createLogtoAdapter: createLogtoAdapter } = deps;
237
+ const session = await sessionStorage.getSession(request.cookieHeader);
238
+ const logto = createLogtoAdapter(session);
239
+ const response = await logto.handleSignIn({
240
+ redirectUri: request.redirectUri
241
+ });
242
+ const cookieHeader = await sessionStorage.commitSession(response.session);
243
+ return {
244
+ cookieHeader: cookieHeader,
245
+ navigateToUrl: response.navigateToUrl
246
+ };
247
+ };
248
+
249
+
250
+ const $4e85595756955e84$export$3c00ad1b716e9134 = (dto, deps)=>async (request)=>{
251
+ const { createLogtoAdapter: createLogtoAdapter , sessionStorage: sessionStorage } = deps;
252
+ const useCase = (0, $b3adef7963962600$export$463099392e1e6404)({
253
+ createLogtoAdapter: createLogtoAdapter,
254
+ sessionStorage: sessionStorage
255
+ });
256
+ const controller = (0, $6ca04f2e8ce3f248$export$8bb8370a824a554b).fromDto({
257
+ useCase: useCase,
258
+ redirectUri: dto.redirectBackTo
259
+ });
260
+ return controller.execute(request);
261
+ };
262
+
263
+
264
+
265
+
266
+ class $21e03cfddf6418cf$export$144a9ac3253d5e56 extends Error {
267
+ static becauseNoCookieHeaderPresent = ()=>new $21e03cfddf6418cf$export$144a9ac3253d5e56({
268
+ code: 1665388541,
269
+ message: `The authentication sign-in callback route can't be accessed without a valid cookie.`
270
+ });
271
+ constructor(properties){
272
+ super(`#[${properties.code}] ${properties.message}`);
273
+ this.properties = properties;
274
+ this.code = this.properties.code;
275
+ this.cause = this.properties.cause;
276
+ this.plainMessage = this.properties.message;
277
+ }
278
+ }
279
+
280
+
281
+ class $f663abe9edb298e3$export$c8d670afaf17c618 {
282
+ static fromDto = (dto)=>new $f663abe9edb298e3$export$c8d670afaf17c618({
283
+ useCase: dto.useCase,
284
+ redirectUri: dto.redirectUri
285
+ });
286
+ constructor(properties){
287
+ this.properties = properties;
288
+ this.useCase = this.properties.useCase;
289
+ this.redirectUri = this.properties.redirectUri;
290
+ this.execute = async (request)=>{
291
+ const cookieHeader = (0, $978a582c6f8c8e7b$export$5c6fae4c79d686e4)(request);
292
+ if (!cookieHeader) throw (0, $21e03cfddf6418cf$export$144a9ac3253d5e56).becauseNoCookieHeaderPresent();
293
+ // In some scenarios, like performing the sign-in callback within a Gitpod
294
+ // environment, the load balancer rewrites the URL and uses `http` as the
295
+ // protocol. Here, we make sure that when the `x-forwarded-proto` HTTP header
296
+ // is present, we will replace `http` with `https` in the `callbackUri`.
297
+ const isForwardedHttpsTraffic = request.headers.get("x-forwarded-proto") === "https";
298
+ const callbackUri = isForwardedHttpsTraffic ? request.url.replace("http", "https") : request.url;
299
+ const result = await this.useCase({
300
+ cookieHeader: cookieHeader,
301
+ callbackUri: callbackUri
302
+ });
303
+ return (0, $jCOgx$remixrunnode.redirect)(this.redirectUri, {
304
+ headers: {
305
+ "Set-Cookie": result.cookieHeader
306
+ }
307
+ });
308
+ };
309
+ }
310
+ }
311
+
312
+
313
+ const $ff5498b695abf304$export$22e357c661ee13a4 = (deps)=>async (request)=>{
314
+ const { sessionStorage: sessionStorage , createLogtoAdapter: createLogtoAdapter } = deps;
315
+ const session = await sessionStorage.getSession(request.cookieHeader);
316
+ const logto = createLogtoAdapter(session);
317
+ const response = await logto.handleSignInCallback({
318
+ callbackUri: request.callbackUri
319
+ });
320
+ const cookieHeader = await sessionStorage.commitSession(response.session);
321
+ return {
322
+ cookieHeader: cookieHeader
323
+ };
324
+ };
325
+
326
+
327
+ const $7a39fdd186e8afdc$export$9c07365b51e93ba3 = (dto, deps)=>async (request)=>{
328
+ const { createLogtoAdapter: createLogtoAdapter , sessionStorage: sessionStorage } = deps;
329
+ const useCase = (0, $ff5498b695abf304$export$22e357c661ee13a4)({
330
+ createLogtoAdapter: createLogtoAdapter,
331
+ sessionStorage: sessionStorage
332
+ });
333
+ const controller = (0, $f663abe9edb298e3$export$c8d670afaf17c618).fromDto({
334
+ useCase: useCase,
335
+ redirectUri: dto.redirectBackTo
336
+ });
337
+ return controller.execute(request);
338
+ };
339
+
340
+
341
+
342
+
343
+ class $311025c6b993527d$export$e01614cfebe90908 extends Error {
344
+ static becauseNoCookieHeaderPresent = ()=>new $311025c6b993527d$export$e01614cfebe90908({
345
+ code: 1665388713,
346
+ message: `The authentication sign-out route can't be accessed without a valid cookie.`
347
+ });
348
+ constructor(properties){
349
+ super(`#[${properties.code}] ${properties.message}`);
350
+ this.properties = properties;
351
+ this.code = this.properties.code;
352
+ this.cause = this.properties.cause;
353
+ this.plainMessage = this.properties.message;
354
+ }
355
+ }
356
+
357
+
358
+ class $dbef723619a85b93$export$543cea0b68ca8887 {
359
+ static fromDto = (dto)=>new $dbef723619a85b93$export$543cea0b68ca8887({
360
+ useCase: dto.useCase,
361
+ redirectUri: dto.redirectUri
362
+ });
363
+ constructor(properties){
364
+ this.properties = properties;
365
+ this.useCase = this.properties.useCase;
366
+ this.redirectUri = this.properties.redirectUri;
367
+ this.execute = async (request)=>{
368
+ const cookieHeader = (0, $978a582c6f8c8e7b$export$5c6fae4c79d686e4)(request);
369
+ if (!cookieHeader) throw (0, $311025c6b993527d$export$e01614cfebe90908).becauseNoCookieHeaderPresent();
370
+ const result = await this.useCase({
371
+ cookieHeader: cookieHeader,
372
+ redirectUri: this.redirectUri
373
+ });
374
+ return (0, $jCOgx$remixrunnode.redirect)(this.redirectUri, {
375
+ headers: {
376
+ "Set-Cookie": result.cookieHeader
377
+ }
378
+ });
379
+ };
380
+ }
381
+ }
382
+
383
+
384
+ const $2453e8ad28193ffe$export$8ccb0e4b7ccc1fc4 = (deps)=>async (request)=>{
385
+ const { sessionStorage: sessionStorage , createLogtoAdapter: createLogtoAdapter } = deps;
386
+ const session = await sessionStorage.getSession(request.cookieHeader);
387
+ const logto = createLogtoAdapter(session);
388
+ const response = await logto.handleSignOut({
389
+ redirectUri: request.redirectUri
390
+ });
391
+ const cookieHeader = await sessionStorage.destroySession(session);
392
+ return {
393
+ cookieHeader: cookieHeader,
394
+ navigateToUrl: response.navigateToUrl
395
+ };
396
+ };
397
+
398
+
399
+ const $380e7b1772b43f91$export$89f18ff1488dade0 = (dto, deps)=>async (request)=>{
400
+ const { createLogtoAdapter: createLogtoAdapter , sessionStorage: sessionStorage } = deps;
401
+ const useCase = (0, $2453e8ad28193ffe$export$8ccb0e4b7ccc1fc4)({
402
+ createLogtoAdapter: createLogtoAdapter,
403
+ sessionStorage: sessionStorage
404
+ });
405
+ const controller = (0, $dbef723619a85b93$export$543cea0b68ca8887).fromDto({
406
+ useCase: useCase,
407
+ redirectUri: dto.redirectBackTo
408
+ });
409
+ return controller.execute(request);
410
+ };
411
+
412
+
413
+ class $1a27034d0b6c1fa0$export$fcbf49abe9908796 extends Error {
414
+ static becauseNoConfigForPath = (anticipatedPath)=>new $1a27034d0b6c1fa0$export$fcbf49abe9908796({
415
+ code: 1665388277,
416
+ message: `No configuration available for path "${anticipatedPath}".`
417
+ });
418
+ static becauseOfUnknownRoute = (anticipatedConfigKey)=>new $1a27034d0b6c1fa0$export$fcbf49abe9908796({
419
+ code: 1665388278,
420
+ message: `The config key "${anticipatedConfigKey}" is invalid.`
421
+ });
422
+ constructor(properties){
423
+ super(`#[${properties.code}] ${properties.message}`);
424
+ this.properties = properties;
425
+ this.code = this.properties.code;
426
+ this.cause = this.properties.cause;
427
+ this.plainMessage = this.properties.message;
428
+ }
429
+ }
430
+
431
+
432
+ const $4726b3ba230d3664$export$d6e32a8c2b1ad7f3 = (deps)=>(dto)=>async ({ request: request })=>{
433
+ const anticipatedPath = new URL(request.url).pathname;
434
+ /* eslint-disable no-restricted-syntax */ const configKey = Object.keys(dto).find((type)=>dto[type].path === anticipatedPath);
435
+ const configExists = Boolean(configKey);
436
+ /* eslint-enable no-restricted-syntax */ if (!configExists) throw (0, $1a27034d0b6c1fa0$export$fcbf49abe9908796).becauseNoConfigForPath(anticipatedPath);
437
+ const { sessionStorage: sessionStorage , createLogtoAdapter: createLogtoAdapter , baseUrl: baseUrl } = deps;
438
+ const config = dto[configKey];
439
+ switch(configKey){
440
+ case "sign-in":
441
+ {
442
+ const handler = (0, $4e85595756955e84$export$3c00ad1b716e9134)({
443
+ redirectBackTo: `${baseUrl}${config.redirectBackTo}`
444
+ }, {
445
+ sessionStorage: sessionStorage,
446
+ createLogtoAdapter: createLogtoAdapter
447
+ });
448
+ return handler(request);
449
+ }
450
+ case "sign-in-callback":
451
+ {
452
+ const handler1 = (0, $7a39fdd186e8afdc$export$9c07365b51e93ba3)({
453
+ redirectBackTo: `${baseUrl}${config.redirectBackTo}`
454
+ }, {
455
+ sessionStorage: sessionStorage,
456
+ createLogtoAdapter: createLogtoAdapter
457
+ });
458
+ return handler1(request);
459
+ }
460
+ case "sign-out":
461
+ {
462
+ const handler2 = (0, $380e7b1772b43f91$export$89f18ff1488dade0)({
463
+ redirectBackTo: `${baseUrl}${config.redirectBackTo}`
464
+ }, {
465
+ sessionStorage: sessionStorage,
466
+ createLogtoAdapter: createLogtoAdapter
467
+ });
468
+ return handler2(request);
469
+ }
470
+ default:
471
+ throw (0, $1a27034d0b6c1fa0$export$fcbf49abe9908796).becauseOfUnknownRoute(configKey);
472
+ }
473
+ };
474
+
475
+
476
+ const $0ca379f5bbbb8613$export$502a4d54d411a9fd = (config, deps)=>{
477
+ const { sessionStorage: sessionStorage } = deps;
478
+ const { baseUrl: baseUrl } = config;
479
+ const createLogtoAdapter = (0, $be51f08b006ed125$export$5e1ab578feca185a)(config);
480
+ return Object.freeze({
481
+ handleAuthRoutes: (0, $4726b3ba230d3664$export$d6e32a8c2b1ad7f3)({
482
+ baseUrl: baseUrl,
483
+ createLogtoAdapter: createLogtoAdapter,
484
+ sessionStorage: sessionStorage
485
+ }),
486
+ getContext: (dto)=>(0, $7b69d37f648a005c$export$f4d9bb4cf5d2b40c)(dto, {
487
+ createLogtoAdapter: createLogtoAdapter,
488
+ sessionStorage: sessionStorage
489
+ })
490
+ });
491
+ };
492
+
493
+
494
+ //# sourceMappingURL=index.js.map