@leaguebrain/provenance 0.0.0-stage → 0.14.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.
@@ -0,0 +1,432 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was generated by 'vite-plugin-provenance'
4
+ *
5
+ * >> DO NOT EDIT THIS FILE MANUALLY <<
6
+ */
7
+ import { redirect, type Handle, type RequestEvent } from '@sveltejs/kit';
8
+ import { sequence } from '@sveltejs/kit/hooks';
9
+
10
+ import {
11
+ o,
12
+ s,
13
+ c,
14
+ r,
15
+ type ChecksModule,
16
+ type OAuthModule,
17
+ type RoutesModule,
18
+ type SessionModule,
19
+ type AuthOptions,
20
+ type Provider,
21
+ type Context,
22
+ type TokenRequestResult
23
+ } from '@leaguebrain/provenance';
24
+
25
+ import { logStarter } from '@leaguebrain/provenance/helpers';
26
+
27
+ import { dev } from '$app/environment';
28
+
29
+ /**
30
+ * @param getDomain use event data to return a value for the session cookie's domain attributes
31
+ * @param logging whether to log in handle routes (will use setting for \`dev\` if not provided)
32
+ * @param options provide options to configure things like pathnames and cookie names (all fields are optional with sensible defaults)
33
+ */
34
+ export type ProvenanceConfig = {
35
+ getDomain?: (event: RequestEvent) => string | undefined;
36
+ logging?: boolean;
37
+ options?: AuthOptions;
38
+ };
39
+
40
+ function createContext<ProviderSession, AppSession extends ProviderSession>(
41
+ event: RequestEvent,
42
+ modules: {
43
+ oauth: OAuthModule;
44
+ session: SessionModule<ProviderSession>;
45
+ routes: RoutesModule;
46
+ checks: ChecksModule<{ referrer?: string }>;
47
+ },
48
+ config: {
49
+ logging: boolean;
50
+ getDomain?: (event: RequestEvent) => string | undefined;
51
+ }
52
+ ): Context<ProviderSession, AppSession> {
53
+ const isRoute = (searchPathname: string) => {
54
+ const pathName = event.url.pathname;
55
+
56
+ return pathName.startsWith(searchPathname);
57
+ };
58
+
59
+ return {
60
+ oauth: {
61
+ processAuthResponse: (expectedState: string) => {
62
+ const url = event.url;
63
+
64
+ if (config.logging) {
65
+ logStarter('oauth:', 'processAuthResponse');
66
+ console.log('url:', url.href);
67
+ console.log('expectedState:', expectedState);
68
+ }
69
+
70
+ const authResponse = modules.oauth.processAuthResponse(url, expectedState);
71
+
72
+ if (config.logging) {
73
+ console.log('authResponse:', authResponse);
74
+ }
75
+
76
+ return authResponse;
77
+ },
78
+ requestToken: async (codeVerifier: string, authorizationCode: string) => {
79
+ const fetchRequestToken = async (
80
+ url: URL,
81
+ params: {
82
+ clientId: string;
83
+ clientSecret: string;
84
+ redirectUri: string;
85
+ }
86
+ ): Promise<Response> => {
87
+ const client_id = params.clientId;
88
+ const client_secret = params.clientSecret;
89
+ const redirect_uri = new URL(params.redirectUri, event.url.origin).toString();
90
+ const grant_type = 'authorization_code';
91
+ const code = authorizationCode;
92
+ const code_verifier = codeVerifier;
93
+
94
+ if (config.logging) {
95
+ console.log('client_id:', client_id);
96
+ console.log('client_secret:', client_secret);
97
+ console.log('redirect_uri:', redirect_uri);
98
+ console.log('grant_type:', grant_type);
99
+ console.log('code:', code);
100
+ console.log('code_verifier:', code_verifier);
101
+ }
102
+
103
+ return await event.fetch(url, {
104
+ method: 'POST',
105
+ headers: {
106
+ 'Content-Type': 'application/x-www-form-urlencoded',
107
+ Accept: 'application/json'
108
+ },
109
+ body: new URLSearchParams({
110
+ client_id: client_id,
111
+ client_secret: client_secret,
112
+ redirect_uri: redirect_uri,
113
+ grant_type: grant_type,
114
+ code: authorizationCode,
115
+ code_verifier: codeVerifier
116
+ })
117
+ });
118
+ };
119
+
120
+ if (config.logging) {
121
+ logStarter('oauth:', 'requestToken');
122
+ }
123
+
124
+ const tokenEndpointResponse = await modules.oauth.requestToken(fetchRequestToken);
125
+
126
+ if (config.logging) {
127
+ console.log('tokenEndpointResponse:', tokenEndpointResponse);
128
+ }
129
+
130
+ return tokenEndpointResponse;
131
+ },
132
+ refresh: async (refreshToken: string) => {
133
+ const fetchRefreshedToken = async (
134
+ url: URL,
135
+ body: {
136
+ client_id: string;
137
+ client_secret: string;
138
+ grant_type: 'refresh_token';
139
+ refresh_token: string;
140
+ }
141
+ ): Promise<Response> => {
142
+ if (config.logging) {
143
+ console.log('client_id:', body.client_id);
144
+ console.log('client_secret:', body.client_secret);
145
+ console.log('grant_type:', body.grant_type);
146
+ console.log('refresh_token:', body.refresh_token);
147
+ }
148
+
149
+ return await event.fetch(url, {
150
+ method: 'POST',
151
+ headers: {
152
+ 'Content-Type': 'application/x-www-form-urlencoded'
153
+ },
154
+ body: new URLSearchParams(body)
155
+ });
156
+ };
157
+
158
+ if (config.logging) {
159
+ logStarter('oauth:', 'refresh');
160
+ }
161
+
162
+ const tokenEndpointResponse = await modules.oauth.refresh(
163
+ fetchRefreshedToken,
164
+ refreshToken
165
+ );
166
+
167
+ if (config.logging) {
168
+ console.log('tokenEndpointResponse:', tokenEndpointResponse);
169
+ }
170
+
171
+ return tokenEndpointResponse;
172
+ },
173
+ referrer: event.url.searchParams.get('referrer'),
174
+ redirectLogin: async (referrer: string | null) => {
175
+ const origin = event.url.origin;
176
+
177
+ if (config.logging) {
178
+ logStarter('oauth:', 'redirectLogin');
179
+ console.log('origin:', origin);
180
+ }
181
+
182
+ return redirect(302, await modules.oauth.login(origin, referrer, event.cookies.set));
183
+ },
184
+ redirectSignup: async (referrer: string | null) => {
185
+ const origin = event.url.origin;
186
+
187
+ if (config.logging) {
188
+ logStarter('oauth:', 'redirectSignup');
189
+ console.log('origin:', origin);
190
+ }
191
+
192
+ return redirect(302, await modules.oauth.signup(origin, referrer, event.cookies.set));
193
+ },
194
+ preLogout: async (session: ProviderSession) => {
195
+ const fetch = async (url: URL, body?: URLSearchParams): Promise<Response> => {
196
+ if (config.logging) {
197
+ console.log('url:', url);
198
+ console.log('body:', body);
199
+ }
200
+
201
+ return await event.fetch(url, {
202
+ method: 'POST',
203
+ headers: {
204
+ 'Content-Type': 'application/x-www-form-urlencoded'
205
+ },
206
+ body: body
207
+ });
208
+ };
209
+
210
+ if (config.logging) {
211
+ logStarter('oauth:', 'preLogout');
212
+ }
213
+
214
+ return await modules.oauth.logout(fetch, session);
215
+ }
216
+ },
217
+ checks: {
218
+ state: {
219
+ use: () => {
220
+ const state = modules.checks.state.use(event.cookies);
221
+
222
+ if (config.logging) {
223
+ logStarter('checks:', 'state:', 'use');
224
+ console.log('state:', state);
225
+ }
226
+
227
+ return state;
228
+ }
229
+ },
230
+ pkce: {
231
+ use: () => {
232
+ const pkce = modules.checks.pkce.use(event.cookies);
233
+
234
+ if (config.logging) {
235
+ logStarter('checks:', 'pkce:', 'use');
236
+ console.log('pkce:', pkce);
237
+ }
238
+
239
+ return pkce;
240
+ }
241
+ }
242
+ },
243
+ session: {
244
+ create: (tokens: TokenRequestResult) => {
245
+ if (config.logging) {
246
+ logStarter('session:', 'create');
247
+ }
248
+
249
+ const session = modules.session.create(tokens);
250
+
251
+ if (config.logging) {
252
+ console.log('session:', session);
253
+ }
254
+
255
+ return session;
256
+ },
257
+ getCookie: () => {
258
+ if (config.logging) {
259
+ logStarter('session:', 'getCookie');
260
+ }
261
+
262
+ const cookie = modules.session.getCookie(event.cookies.getAll);
263
+
264
+ if (config.logging) {
265
+ console.log('cookie:', cookie);
266
+ }
267
+
268
+ return cookie;
269
+ },
270
+ setCookie: (session: ProviderSession) => {
271
+ if (config.logging) {
272
+ logStarter('session:', 'setCookie');
273
+ console.log('session:', session);
274
+ }
275
+
276
+ const domain = config.getDomain?.(event);
277
+
278
+ modules.session.setCookie((name, value, maxAge) => {
279
+ if (config.logging) {
280
+ console.log('name:', name);
281
+ console.log('value:', value);
282
+ console.log('maxAge:', maxAge);
283
+ console.log('domain:', domain);
284
+ }
285
+
286
+ return event.cookies.set(name, value, {
287
+ path: '/',
288
+ maxAge,
289
+ domain
290
+ });
291
+ }, session);
292
+ },
293
+ deleteCookie: () => {
294
+ if (config.logging) {
295
+ logStarter('session:', 'deleteCookie');
296
+ }
297
+
298
+ const domain = config.getDomain?.(event);
299
+
300
+ modules.session.deleteCookie(event.cookies.getAll, (name) => {
301
+ if (config.logging) {
302
+ console.log('name:', name);
303
+ console.log('domain:', domain);
304
+ }
305
+
306
+ event.cookies.delete(name, {
307
+ path: '/',
308
+ domain
309
+ });
310
+ });
311
+ }
312
+ },
313
+ locals: {
314
+ get session() {
315
+ return event.locals.session as AppSession;
316
+ },
317
+ set session(value) {
318
+ event.locals.session = value as App.Session;
319
+ }
320
+ },
321
+ routes: {
322
+ redirect: (location) => {
323
+ return redirect(302, location);
324
+ },
325
+ redirectUri: {
326
+ is: isRoute(modules.routes.redirectUri.pathname)
327
+ },
328
+ login: {
329
+ redirect: () => {
330
+ const loginPathname = modules.routes.login.pathname;
331
+
332
+ const loginPath = `${loginPathname}?${new URLSearchParams({ referrer: event.url.pathname + event.url.search })}`;
333
+
334
+ return redirect(302, loginPath);
335
+ },
336
+ is: isRoute(modules.routes.login.pathname)
337
+ },
338
+ signup: {
339
+ redirect: () => {
340
+ const signupPathname = modules.routes.signup.pathname;
341
+
342
+ const signupPath = `${signupPathname}?${new URLSearchParams({ referrer: event.url.pathname + event.url.search })}`;
343
+
344
+ return redirect(302, signupPath);
345
+ },
346
+ is: isRoute(modules.routes.signup.pathname)
347
+ },
348
+ logout: {
349
+ redirect: () => {
350
+ const logoutPathname = modules.routes.logout.pathname;
351
+
352
+ const logoutPath = `${logoutPathname}?${new URLSearchParams({ referrer: event.url.pathname + event.url.search })}`;
353
+
354
+ return redirect(302, logoutPath);
355
+ },
356
+ is: isRoute(modules.routes.logout.pathname)
357
+ },
358
+ home: {
359
+ redirect: () => {
360
+ const homePath = modules.routes.home.pathname;
361
+
362
+ if (config.logging) {
363
+ logStarter('routes:', 'home:', 'redirect');
364
+ console.log('homePath:', homePath);
365
+ }
366
+
367
+ return redirect(302, homePath);
368
+ },
369
+ is: isRoute(modules.routes.home.pathname)
370
+ }
371
+ }
372
+ };
373
+ }
374
+
375
+ /**
376
+ * @param provider configuration for your OAuth provider ([see](@leaguebrain/provenance/providers/index.ts))
377
+ * @param config optional extra configuration options for provenance behaviour
378
+ * @returns an auth object with handle to be used in \`hooks.server.ts\` and \`protectRoute\` to redirect to login from \`+page.server.ts\` load functions if user is not authenticated
379
+ */
380
+ export const provenance = <ProviderSession>(
381
+ provider: Provider<ProviderSession>,
382
+ config?: ProvenanceConfig
383
+ ) => {
384
+ const defaultedOptions = {
385
+ redirectUriPathname: '/auth',
386
+ sessionCookieName: 'session',
387
+ loginPathname: '/login',
388
+ signupPathname: '/signup',
389
+ logoutPathname: '/logout',
390
+ refreshPathname: '/refresh',
391
+ homePathname: '/',
392
+ ...config?.options
393
+ };
394
+
395
+ const defaultedConfig = {
396
+ logging: dev,
397
+ ...config
398
+ };
399
+
400
+ const checks = c();
401
+ const routes = r(defaultedOptions);
402
+ const oauth = o({ checks }, provider, defaultedOptions);
403
+ const session = s(provider, defaultedOptions);
404
+
405
+ const handles = provider.resolvers.map((resolver) => {
406
+ const handle: Handle = async ({ event, resolve }) => {
407
+ const context = createContext(event, { checks, oauth, session, routes }, defaultedConfig);
408
+
409
+ return await resolver(context, async () => await resolve(event), defaultedConfig.logging);
410
+ };
411
+ return handle;
412
+ });
413
+
414
+ return {
415
+ handle: sequence(...handles),
416
+ options: defaultedOptions,
417
+ createContext: (event: RequestEvent) =>
418
+ createContext(event, { checks, oauth, session, routes }, defaultedConfig)
419
+ };
420
+ };
421
+
422
+ declare global {
423
+ namespace App {
424
+ interface Session {}
425
+
426
+ interface Locals {
427
+ session: Session | null;
428
+ }
429
+ }
430
+ }
431
+
432
+ export {};