@absolutejs/auth 0.43.0 → 0.44.1

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,2558 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+ var __require = import.meta.require;
18
+
19
+ // node_modules/citra/dist/index.js
20
+ var BASE64_BLOCK_SIZE = 4;
21
+ var NUM_GENERATOR_BYTES = 32;
22
+ var anilistProfileQuery = `query {
23
+ Viewer {
24
+ id
25
+ name
26
+ about
27
+ avatar {
28
+ large
29
+ medium
30
+ }
31
+ bannerImage
32
+ siteUrl
33
+ createdAt
34
+ updatedAt
35
+ donatorTier
36
+ donatorBadge
37
+ unreadNotificationCount
38
+ options {
39
+ titleLanguage
40
+ displayAdultContent
41
+ airingNotifications
42
+ profileColor
43
+ activityMergeTime
44
+ staffNameLanguage
45
+ }
46
+ mediaListOptions {
47
+ scoreFormat
48
+ rowOrder
49
+ animeList {
50
+ sectionOrder
51
+ customLists
52
+ advancedScoringEnabled
53
+ }
54
+ mangaList {
55
+ sectionOrder
56
+ customLists
57
+ advancedScoringEnabled
58
+ }
59
+ }
60
+ statistics {
61
+ anime {
62
+ count
63
+ meanScore
64
+ minutesWatched
65
+ episodesWatched
66
+ }
67
+ manga {
68
+ count
69
+ meanScore
70
+ chaptersRead
71
+ volumesRead
72
+ }
73
+ }
74
+ favourites {
75
+ anime {
76
+ nodes {
77
+ id
78
+ title {
79
+ romaji
80
+ english
81
+ }
82
+ siteUrl
83
+ }
84
+ }
85
+ manga {
86
+ nodes {
87
+ id
88
+ title {
89
+ romaji
90
+ english
91
+ }
92
+ siteUrl
93
+ }
94
+ }
95
+ characters {
96
+ nodes {
97
+ id
98
+ name {
99
+ full
100
+ }
101
+ image {
102
+ large
103
+ }
104
+ }
105
+ }
106
+ staff {
107
+ nodes {
108
+ id
109
+ name {
110
+ full
111
+ }
112
+ image {
113
+ large
114
+ }
115
+ }
116
+ }
117
+ studios {
118
+ nodes {
119
+ id
120
+ name
121
+ siteUrl
122
+ }
123
+ }
124
+ }
125
+ isFollower
126
+ isFollowing
127
+ }
128
+ }`;
129
+ var defineProviders = (providers) => providers;
130
+ var providers = defineProviders({
131
+ "42": {
132
+ authorizationUrl: "https://api.intra.42.fr/oauth/authorize",
133
+ isOIDC: false,
134
+ isRefreshable: true,
135
+ profileRequest: {
136
+ authIn: "header",
137
+ encoding: "application/json",
138
+ method: "GET",
139
+ url: "https://api.intra.42.fr/v2/me"
140
+ },
141
+ scopeRequired: false,
142
+ subject: ["id"],
143
+ subjectType: "string",
144
+ tokenRequest: {
145
+ authIn: "body",
146
+ encoding: "application/x-www-form-urlencoded",
147
+ url: "https://api.intra.42.fr/oauth/token"
148
+ }
149
+ },
150
+ amazoncognito: {
151
+ authorizationUrl: "https://${domain}/oauth2/authorize",
152
+ isOIDC: true,
153
+ isRefreshable: true,
154
+ PKCEMethod: "S256",
155
+ profileRequest: {
156
+ authIn: "header",
157
+ encoding: "application/json",
158
+ method: "GET",
159
+ url: (config) => `https://${config.domain}/oauth2/userInfo`
160
+ },
161
+ revocationRequest: {
162
+ authIn: "body",
163
+ encoding: "application/json",
164
+ tokenParamName: "token",
165
+ url: (config) => `https://${config.domain}/oauth2/revoke`
166
+ },
167
+ scopeRequired: false,
168
+ subject: ["id"],
169
+ subjectType: "string",
170
+ tokenRequest: {
171
+ authIn: "body",
172
+ encoding: "application/x-www-form-urlencoded",
173
+ url: (config) => `https://${config.domain}/oauth2/token`
174
+ }
175
+ },
176
+ anilist: {
177
+ authorizationUrl: "https://anilist.co/api/v2/oauth/authorize",
178
+ isOIDC: false,
179
+ isRefreshable: true,
180
+ profileRequest: {
181
+ authIn: "header",
182
+ body: {
183
+ query: anilistProfileQuery
184
+ },
185
+ encoding: "application/json",
186
+ headers: {
187
+ Accept: "application/json",
188
+ "Content-Type": "application/json"
189
+ },
190
+ method: "POST",
191
+ url: "https://graphql.anilist.co"
192
+ },
193
+ scopeRequired: false,
194
+ subject: ["data", "Viewer", "id"],
195
+ subjectType: "number",
196
+ tokenRequest: {
197
+ authIn: "body",
198
+ encoding: "application/x-www-form-urlencoded",
199
+ url: "https://anilist.co/api/v2/oauth/token"
200
+ }
201
+ },
202
+ apple: {
203
+ authorizationUrl: "https://appleid.apple.com/auth/authorize",
204
+ isOIDC: true,
205
+ isRefreshable: true,
206
+ PKCEMethod: "S256",
207
+ profileRequest: {
208
+ authIn: "header",
209
+ encoding: "application/json",
210
+ method: "GET",
211
+ url: "https://appleid.apple.com/auth/userinfo"
212
+ },
213
+ scopeRequired: false,
214
+ subject: ["id"],
215
+ subjectType: "string",
216
+ tokenRequest: {
217
+ authIn: "body",
218
+ encoding: "application/x-www-form-urlencoded",
219
+ url: "https://appleid.apple.com/auth/token"
220
+ }
221
+ },
222
+ atlassian: {
223
+ authorizationUrl: "https://auth.atlassian.com/authorize",
224
+ createAuthorizationURLSearchParams: {
225
+ audience: "api.atlassian.com"
226
+ },
227
+ email: ["email"],
228
+ fullName: ["name"],
229
+ isOIDC: false,
230
+ isRefreshable: true,
231
+ picture: ["picture"],
232
+ profileRequest: {
233
+ authIn: "header",
234
+ encoding: "application/json",
235
+ method: "GET",
236
+ url: "https://api.atlassian.com/me"
237
+ },
238
+ scopeRequired: true,
239
+ subject: ["account_id"],
240
+ subjectType: "string",
241
+ tokenRequest: {
242
+ authIn: "body",
243
+ encoding: "application/x-www-form-urlencoded",
244
+ url: "https://auth.atlassian.com/oauth/token"
245
+ }
246
+ },
247
+ attio: {
248
+ authorizationUrl: "https://app.attio.com/authorize",
249
+ isOIDC: false,
250
+ isRefreshable: true,
251
+ profileRequest: {
252
+ authIn: "header",
253
+ encoding: "application/json",
254
+ method: "GET",
255
+ url: "https://api.attio.com/v2/self"
256
+ },
257
+ scopeRequired: true,
258
+ subject: ["workspace_id"],
259
+ subjectType: "string",
260
+ tokenRequest: {
261
+ authIn: "body",
262
+ encoding: "application/x-www-form-urlencoded",
263
+ url: "https://app.attio.com/oauth/token"
264
+ }
265
+ },
266
+ auth0: {
267
+ authorizationUrl: (config) => `https://${config.domain}/authorize`,
268
+ isOIDC: true,
269
+ isRefreshable: true,
270
+ PKCEMethod: "S256",
271
+ profileRequest: {
272
+ authIn: "header",
273
+ encoding: "application/json",
274
+ method: "GET",
275
+ url: (config) => `https://${config.domain}/userinfo`
276
+ },
277
+ revocationRequest: {
278
+ authIn: "body",
279
+ body: new URLSearchParams({
280
+ token_type_hint: "refresh_token"
281
+ }),
282
+ encoding: "application/json",
283
+ tokenParamName: "token",
284
+ url: (config) => `https://${config.domain}/oauth/revoke`
285
+ },
286
+ scopeRequired: false,
287
+ subject: ["id"],
288
+ subjectType: "string",
289
+ tokenRequest: {
290
+ authIn: "body",
291
+ encoding: "application/x-www-form-urlencoded",
292
+ url: (config) => `https://${config.domain}/oauth/token`
293
+ }
294
+ },
295
+ authentik: {
296
+ authorizationUrl: (config) => `https://${config.baseURL}/oauth/authorize`,
297
+ isOIDC: true,
298
+ isRefreshable: true,
299
+ PKCEMethod: "S256",
300
+ profileRequest: {
301
+ authIn: "header",
302
+ encoding: "application/json",
303
+ method: "GET",
304
+ url: (config) => `https://${config.baseURL}/api/v3/user/`
305
+ },
306
+ scopeRequired: false,
307
+ subject: ["id"],
308
+ subjectType: "string",
309
+ tokenRequest: {
310
+ authIn: "body",
311
+ encoding: "application/x-www-form-urlencoded",
312
+ url: (config) => `https://${config.baseURL}/oauth/token`
313
+ }
314
+ },
315
+ autodesk: {
316
+ authorizationUrl: "https://developer.api.autodesk.com/authentication/v2/authorize",
317
+ email: ["email"],
318
+ familyName: ["family_name"],
319
+ fullName: ["name"],
320
+ givenName: ["given_name"],
321
+ isOIDC: true,
322
+ isRefreshable: true,
323
+ picture: ["picture"],
324
+ PKCEMethod: "S256",
325
+ profileRequest: {
326
+ authIn: "header",
327
+ encoding: "application/json",
328
+ method: "GET",
329
+ url: "https://api.userprofile.autodesk.com/userinfo"
330
+ },
331
+ scopeRequired: false,
332
+ subject: ["id"],
333
+ subjectType: "string",
334
+ tokenRequest: {
335
+ authIn: "body",
336
+ encoding: "application/x-www-form-urlencoded",
337
+ url: "https://developer.api.autodesk.com/authentication/v2/token"
338
+ }
339
+ },
340
+ battlenet: {
341
+ authorizationUrl: "https://oauth.battle.net/authorize",
342
+ isOIDC: true,
343
+ isRefreshable: false,
344
+ profileRequest: {
345
+ authIn: "header",
346
+ encoding: "application/json",
347
+ method: "GET",
348
+ url: "https://oauth.battle.net/userinfo"
349
+ },
350
+ scopeRequired: false,
351
+ subject: ["id"],
352
+ subjectType: "string",
353
+ tokenRequest: {
354
+ authIn: "body",
355
+ encoding: "application/x-www-form-urlencoded",
356
+ url: "https://oauth.battle.net/token"
357
+ }
358
+ },
359
+ bitbucket: {
360
+ authorizationUrl: "https://bitbucket.org/site/oauth2/authorize",
361
+ fullName: ["display_name"],
362
+ isOIDC: false,
363
+ isRefreshable: true,
364
+ picture: ["links", "avatar", "href"],
365
+ profileRequest: {
366
+ authIn: "header",
367
+ encoding: "application/json",
368
+ method: "GET",
369
+ url: "https://api.bitbucket.org/2.0/user"
370
+ },
371
+ scopeRequired: false,
372
+ subject: ["uuid"],
373
+ subjectType: "string",
374
+ tokenRequest: {
375
+ authIn: "body",
376
+ encoding: "application/x-www-form-urlencoded",
377
+ url: "https://bitbucket.org/site/oauth2/access_token"
378
+ }
379
+ },
380
+ box: {
381
+ authorizationUrl: "https://account.box.com/api/oauth2/authorize",
382
+ email: ["login"],
383
+ fullName: ["name"],
384
+ isOIDC: false,
385
+ isRefreshable: true,
386
+ picture: ["avatar_url"],
387
+ profileRequest: {
388
+ authIn: "header",
389
+ encoding: "application/json",
390
+ method: "GET",
391
+ url: "https://api.box.com/2.0/users/me"
392
+ },
393
+ revocationRequest: {
394
+ authIn: "body",
395
+ encoding: "application/json",
396
+ tokenParamName: "token",
397
+ url: "https://api.box.com/oauth2/revoke"
398
+ },
399
+ scopeRequired: false,
400
+ subject: ["id"],
401
+ subjectType: "string",
402
+ tokenRequest: {
403
+ authIn: "body",
404
+ encoding: "application/x-www-form-urlencoded",
405
+ url: "https://api.box.com/oauth2/token"
406
+ }
407
+ },
408
+ bungie: {
409
+ authorizationUrl: "https://www.bungie.net/en/OAuth/Authorize",
410
+ isOIDC: false,
411
+ isRefreshable: true,
412
+ profileRequest: {
413
+ authIn: "header",
414
+ encoding: "application/json",
415
+ headers: {
416
+ "X-API-Key": "<YOUR_API_KEY>"
417
+ },
418
+ method: "GET",
419
+ url: "https://www.bungie.net/Platform/User/GetCurrentBungieNetUser"
420
+ },
421
+ scopeRequired: false,
422
+ subject: ["Response", "membershipId"],
423
+ subjectType: "number",
424
+ tokenRequest: {
425
+ authIn: "body",
426
+ encoding: "application/x-www-form-urlencoded",
427
+ url: "https://www.bungie.net/Platform/App/OAuth/token"
428
+ }
429
+ },
430
+ close: {
431
+ authorizationUrl: "https://app.close.com/oauth2/authorize/",
432
+ isOIDC: false,
433
+ isRefreshable: true,
434
+ profileRequest: {
435
+ authIn: "header",
436
+ encoding: "application/json",
437
+ method: "GET",
438
+ url: "https://api.close.com/api/v1/me/"
439
+ },
440
+ scopeRequired: true,
441
+ subject: ["id"],
442
+ subjectType: "string",
443
+ tokenRequest: {
444
+ authIn: "body",
445
+ encoding: "application/x-www-form-urlencoded",
446
+ url: "https://api.close.com/oauth2/token/"
447
+ }
448
+ },
449
+ coinbase: {
450
+ authorizationUrl: "https://www.coinbase.com/oauth/authorize",
451
+ isOIDC: false,
452
+ isRefreshable: true,
453
+ profileRequest: {
454
+ authIn: "header",
455
+ encoding: "application/json",
456
+ method: "GET",
457
+ url: "https://api.coinbase.com/v2/user"
458
+ },
459
+ scopeRequired: false,
460
+ subject: ["data", "id"],
461
+ subjectType: "number",
462
+ tokenRequest: {
463
+ authIn: "body",
464
+ encoding: "application/x-www-form-urlencoded",
465
+ url: "https://api.coinbase.com/oauth/token"
466
+ }
467
+ },
468
+ discord: {
469
+ authorizationUrl: "https://discord.com/api/oauth2/authorize",
470
+ email: ["email"],
471
+ isOIDC: true,
472
+ isRefreshable: true,
473
+ picture: ["avatar"],
474
+ PKCEMethod: "S256",
475
+ profileRequest: {
476
+ authIn: "header",
477
+ encoding: "application/json",
478
+ method: "GET",
479
+ url: "https://discord.com/api/users/@me"
480
+ },
481
+ scopeRequired: true,
482
+ subject: ["id"],
483
+ subjectType: "string",
484
+ tokenRequest: {
485
+ authIn: "body",
486
+ encoding: "application/x-www-form-urlencoded",
487
+ url: "https://discord.com/api/oauth2/token"
488
+ }
489
+ },
490
+ donationalerts: {
491
+ authorizationUrl: "https://www.donationalerts.com/oauth/authorize",
492
+ email: ["data", "email"],
493
+ isOIDC: false,
494
+ isRefreshable: true,
495
+ picture: ["data", "avatar"],
496
+ profileRequest: {
497
+ authIn: "header",
498
+ encoding: "application/json",
499
+ method: "GET",
500
+ url: "https://www.donationalerts.com/api/v1/user/oauth"
501
+ },
502
+ scopeRequired: false,
503
+ subject: ["data", "id"],
504
+ subjectType: "number",
505
+ tokenRequest: {
506
+ authIn: "body",
507
+ encoding: "application/x-www-form-urlencoded",
508
+ url: "https://www.donationalerts.com/oauth/token"
509
+ }
510
+ },
511
+ dribbble: {
512
+ authorizationUrl: "https://dribbble.com/oauth/authorize",
513
+ isOIDC: false,
514
+ isRefreshable: false,
515
+ profileRequest: {
516
+ authIn: "header",
517
+ encoding: "application/json",
518
+ method: "GET",
519
+ url: "https://api.dribbble.com/v2/user"
520
+ },
521
+ scopeRequired: false,
522
+ subject: ["id"],
523
+ subjectType: "number",
524
+ tokenRequest: {
525
+ authIn: "body",
526
+ encoding: "application/x-www-form-urlencoded",
527
+ url: "https://dribbble.com/oauth/token"
528
+ }
529
+ },
530
+ dropbox: {
531
+ authorizationUrl: "https://www.dropbox.com/oauth2/authorize",
532
+ email: ["email"],
533
+ familyName: ["name", "surname"],
534
+ fullName: ["name", "display_name"],
535
+ givenName: ["name", "given_name"],
536
+ isOIDC: false,
537
+ isRefreshable: true,
538
+ profileRequest: {
539
+ authIn: "header",
540
+ encoding: "application/json",
541
+ method: "POST",
542
+ url: "https://api.dropboxapi.com/2/users/get_current_account"
543
+ },
544
+ revocationRequest: {
545
+ authIn: "header",
546
+ encoding: "application/json",
547
+ url: "https://api.dropboxapi.com/2/auth/token/revoke"
548
+ },
549
+ scopeRequired: false,
550
+ subject: ["account_id"],
551
+ subjectType: "string",
552
+ tokenRequest: {
553
+ authIn: "body",
554
+ encoding: "application/x-www-form-urlencoded",
555
+ url: "https://api.dropboxapi.com/oauth2/token"
556
+ }
557
+ },
558
+ epicgames: {
559
+ authorizationUrl: "https://www.epicgames.com/id/authorize",
560
+ isOIDC: false,
561
+ isRefreshable: true,
562
+ profileRequest: {
563
+ authIn: "header",
564
+ encoding: "application/json",
565
+ method: "GET",
566
+ url: "https://api.epicgames.dev/epic/oauth/v2/userInfo"
567
+ },
568
+ scopeRequired: false,
569
+ subject: ["account_id"],
570
+ subjectType: "number",
571
+ tokenRequest: {
572
+ authIn: "body",
573
+ encoding: "application/x-www-form-urlencoded",
574
+ url: "https://api.epicgames.dev/epic/oauth/v1/token"
575
+ }
576
+ },
577
+ etsy: {
578
+ authorizationUrl: "https://www.etsy.com/oauth/connect",
579
+ isOIDC: false,
580
+ isRefreshable: true,
581
+ profileRequest: {
582
+ authIn: "header",
583
+ encoding: "application/json",
584
+ method: "GET",
585
+ url: "https://openapi.etsy.com/v3/application/users/me"
586
+ },
587
+ scopeRequired: false,
588
+ subject: ["results", "0", "user_id"],
589
+ subjectType: "number",
590
+ tokenRequest: {
591
+ authIn: "body",
592
+ encoding: "application/x-www-form-urlencoded",
593
+ url: "https://api.etsy.com/v3/public/oauth/token"
594
+ }
595
+ },
596
+ facebook: {
597
+ authorizationUrl: "https://www.facebook.com/v16.0/dialog/oauth",
598
+ email: ["email"],
599
+ familyName: ["family_name"],
600
+ fullName: ["name"],
601
+ givenName: ["given_name"],
602
+ isOIDC: true,
603
+ isRefreshable: false,
604
+ picture: ["picture"],
605
+ PKCEMethod: "S256",
606
+ profileRequest: {
607
+ authIn: "query",
608
+ encoding: "application/json",
609
+ method: "GET",
610
+ searchParams: [["fields", "id,name,email,picture"]],
611
+ url: "https://graph.facebook.com/me"
612
+ },
613
+ scopeRequired: false,
614
+ subject: ["sub"],
615
+ subjectBySource: {
616
+ idToken: ["sub"],
617
+ profile: ["id"]
618
+ },
619
+ subjectType: "string",
620
+ tokenRequest: {
621
+ authIn: "body",
622
+ encoding: "application/x-www-form-urlencoded",
623
+ url: "https://graph.facebook.com/v16.0/oauth/access_token"
624
+ }
625
+ },
626
+ figma: {
627
+ authorizationUrl: "https://www.figma.com/oauth",
628
+ email: ["email"],
629
+ isOIDC: false,
630
+ isRefreshable: true,
631
+ picture: ["img_url"],
632
+ PKCEMethod: "S256",
633
+ profileRequest: {
634
+ authIn: "header",
635
+ encoding: "application/json",
636
+ method: "GET",
637
+ url: "https://api.figma.com/v1/me"
638
+ },
639
+ scopeRequired: true,
640
+ subject: ["id"],
641
+ subjectType: "string",
642
+ tokenRequest: {
643
+ authIn: "body",
644
+ encoding: "application/x-www-form-urlencoded",
645
+ url: "https://api.figma.com/v1/oauth/token"
646
+ }
647
+ },
648
+ gitea: {
649
+ authorizationUrl: (config) => `${config.baseURL}/login/oauth/authorize`,
650
+ isOIDC: true,
651
+ isRefreshable: true,
652
+ PKCEMethod: "S256",
653
+ profileRequest: {
654
+ authIn: "header",
655
+ encoding: "application/json",
656
+ method: "GET",
657
+ url: (config) => `${config.baseURL}/api/v1/user`
658
+ },
659
+ scopeRequired: false,
660
+ subject: ["id"],
661
+ subjectType: "string",
662
+ tokenRequest: {
663
+ authIn: "body",
664
+ encoding: "application/x-www-form-urlencoded",
665
+ url: (config) => `${config.baseURL}/login/oauth/access_token`
666
+ }
667
+ },
668
+ github: {
669
+ authorizationUrl: "https://github.com/login/oauth/authorize",
670
+ email: ["email"],
671
+ isOIDC: false,
672
+ isRefreshable: false,
673
+ picture: ["avatar_url"],
674
+ profileRequest: {
675
+ authIn: "header",
676
+ encoding: "application/json",
677
+ method: "GET",
678
+ url: "https://api.github.com/user"
679
+ },
680
+ scopeRequired: false,
681
+ subject: ["id"],
682
+ subjectType: "number",
683
+ tokenRequest: {
684
+ authIn: "body",
685
+ encoding: "application/x-www-form-urlencoded",
686
+ url: "https://github.com/login/oauth/access_token"
687
+ }
688
+ },
689
+ gitlab: {
690
+ authorizationUrl: (config) => `${config.baseURL}/oauth/authorize`,
691
+ email: ["email"],
692
+ fullName: ["name"],
693
+ isOIDC: true,
694
+ isRefreshable: true,
695
+ picture: ["picture"],
696
+ PKCEMethod: "S256",
697
+ profileRequest: {
698
+ authIn: "header",
699
+ encoding: "application/json",
700
+ method: "GET",
701
+ url: "https://gitlab.com/api/v4/user"
702
+ },
703
+ revocationRequest: {
704
+ authIn: "body",
705
+ encoding: "application/json",
706
+ tokenParamName: "token",
707
+ url: (config) => `${config.baseURL}/oauth/revoke`
708
+ },
709
+ scopeRequired: false,
710
+ subject: ["id"],
711
+ subjectType: "string",
712
+ tokenRequest: {
713
+ authIn: "body",
714
+ encoding: "application/x-www-form-urlencoded",
715
+ url: (config) => `${config.baseURL}/oauth/token`
716
+ }
717
+ },
718
+ gohighlevel: {
719
+ authorizationUrl: "https://marketplace.gohighlevel.com/oauth/chooselocation",
720
+ isOIDC: false,
721
+ isRefreshable: true,
722
+ profileRequest: {
723
+ authIn: "header",
724
+ encoding: "application/json",
725
+ method: "GET",
726
+ url: "https://services.leadconnectorhq.com/users/me"
727
+ },
728
+ scopeRequired: true,
729
+ subject: ["id"],
730
+ subjectType: "string",
731
+ tokenRequest: {
732
+ authIn: "body",
733
+ encoding: "application/x-www-form-urlencoded",
734
+ url: "https://services.leadconnectorhq.com/oauth/token"
735
+ }
736
+ },
737
+ google: {
738
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
739
+ email: ["email"],
740
+ familyName: ["family_name"],
741
+ fullName: ["name"],
742
+ givenName: ["given_name"],
743
+ isOIDC: true,
744
+ isRefreshable: true,
745
+ picture: ["picture"],
746
+ PKCEMethod: "S256",
747
+ profileRequest: {
748
+ authIn: "header",
749
+ encoding: "application/json",
750
+ method: "GET",
751
+ url: "https://openidconnect.googleapis.com/v1/userinfo"
752
+ },
753
+ revocationRequest: {
754
+ authIn: "body",
755
+ encoding: "application/json",
756
+ tokenParamName: "token",
757
+ url: "https://oauth2.googleapis.com/revoke"
758
+ },
759
+ scopeRequired: true,
760
+ subject: ["sub"],
761
+ subjectBySource: {
762
+ idToken: ["sub"],
763
+ profile: ["sub"]
764
+ },
765
+ subjectType: "string",
766
+ tokenRequest: {
767
+ authIn: "body",
768
+ encoding: "application/x-www-form-urlencoded",
769
+ url: "https://oauth2.googleapis.com/token"
770
+ }
771
+ },
772
+ hubspot: {
773
+ authorizationUrl: "https://app.hubspot.com/oauth/authorize",
774
+ isOIDC: false,
775
+ isRefreshable: true,
776
+ profileRequest: {
777
+ authIn: "header",
778
+ encoding: "application/json",
779
+ method: "GET",
780
+ url: "https://api.hubapi.com/oauth/v1/access-tokens/me"
781
+ },
782
+ scopeRequired: true,
783
+ subject: ["hub_id"],
784
+ subjectType: "number",
785
+ tokenRequest: {
786
+ authIn: "body",
787
+ encoding: "application/x-www-form-urlencoded",
788
+ url: "https://api.hubapi.com/oauth/v1/token"
789
+ }
790
+ },
791
+ intuit: {
792
+ authorizationUrl: "https://appcenter.intuit.com/connect/oauth2",
793
+ isOIDC: true,
794
+ isRefreshable: true,
795
+ profileRequest: {
796
+ authIn: "header",
797
+ encoding: "application/json",
798
+ method: "GET",
799
+ url: (config) => config.environment === "production" ? "https://accounts.platform.intuit.com/v1/openid_connect/userinfo" : "https://sandbox-accounts.platform.intuit.com/v1/openid_connect/userinfo"
800
+ },
801
+ revocationRequest: {
802
+ authIn: "body",
803
+ encoding: "application/json",
804
+ headers: (config) => ({
805
+ Authorization: `Basic ${encodeBase64(`${config.clientId}:${config.clientSecret}`)}`
806
+ }),
807
+ tokenParamName: "token",
808
+ url: "https://developer.api.intuit.com/v2/oauth2/tokens/revoke"
809
+ },
810
+ scopeRequired: true,
811
+ subject: ["id"],
812
+ subjectType: "string",
813
+ tokenRequest: {
814
+ authIn: "body",
815
+ encoding: "application/x-www-form-urlencoded",
816
+ url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
817
+ }
818
+ },
819
+ kakao: {
820
+ authorizationUrl: "https://kauth.kakao.com/oauth/authorize",
821
+ isOIDC: true,
822
+ isRefreshable: true,
823
+ picture: ["picture"],
824
+ PKCEMethod: "S256",
825
+ profileRequest: {
826
+ authIn: "header",
827
+ encoding: "application/json",
828
+ method: "GET",
829
+ url: "https://kapi.kakao.com/v2/user/me"
830
+ },
831
+ scopeRequired: false,
832
+ subject: ["id"],
833
+ subjectType: "string",
834
+ tokenRequest: {
835
+ authIn: "body",
836
+ encoding: "application/x-www-form-urlencoded",
837
+ url: "https://kauth.kakao.com/oauth/token"
838
+ }
839
+ },
840
+ keycloak: {
841
+ authorizationUrl: (config) => `${config.realmURL}/protocol/openid-connect/auth`,
842
+ isOIDC: true,
843
+ isRefreshable: true,
844
+ PKCEMethod: "S256",
845
+ profileRequest: {
846
+ authIn: "header",
847
+ encoding: "application/json",
848
+ method: "GET",
849
+ url: "https://api.kick.com/v1/user"
850
+ },
851
+ revocationRequest: {
852
+ authIn: "body",
853
+ encoding: "application/json",
854
+ tokenParamName: "token",
855
+ url: (config) => `${config.realmURL}/protocol/openid-connect/revoke`
856
+ },
857
+ scopeRequired: false,
858
+ subject: ["id"],
859
+ subjectType: "string",
860
+ tokenRequest: {
861
+ authIn: "body",
862
+ encoding: "application/x-www-form-urlencoded",
863
+ url: (config) => `${config.realmURL}/protocol/openid-connect/token`
864
+ }
865
+ },
866
+ kick: {
867
+ authorizationUrl: "https://id.kick.com/oauth/authorize",
868
+ email: ["data", "email"],
869
+ isOIDC: false,
870
+ isRefreshable: true,
871
+ picture: ["data", "profile_picture"],
872
+ PKCEMethod: "S256",
873
+ profileRequest: {
874
+ authIn: "header",
875
+ encoding: "application/json",
876
+ method: "GET",
877
+ url: "https://api.kick.com/public/v1/users"
878
+ },
879
+ revocationRequest: {
880
+ authIn: "body",
881
+ encoding: "application/json",
882
+ tokenParamName: "token",
883
+ url: "https://id.kick.com/oauth/revoke"
884
+ },
885
+ scopeRequired: true,
886
+ subject: ["data", "user_id"],
887
+ subjectType: "number",
888
+ tokenRequest: {
889
+ authIn: "body",
890
+ encoding: "application/x-www-form-urlencoded",
891
+ url: "https://id.kick.com/oauth/token"
892
+ }
893
+ },
894
+ lichess: {
895
+ authorizationUrl: "https://lichess.org/oauth/authorize",
896
+ isOIDC: false,
897
+ isRefreshable: false,
898
+ PKCEMethod: "S256",
899
+ profileRequest: {
900
+ authIn: "header",
901
+ encoding: "application/json",
902
+ method: "GET",
903
+ url: "https://lichess.org/api/account"
904
+ },
905
+ scopeRequired: false,
906
+ subject: ["id"],
907
+ subjectType: "string",
908
+ tokenRequest: {
909
+ authIn: "body",
910
+ encoding: "application/x-www-form-urlencoded",
911
+ url: "https://lichess.org/api/token"
912
+ }
913
+ },
914
+ line: {
915
+ authorizationUrl: "https://access.line.me/oauth2/v2.1/authorize",
916
+ isOIDC: true,
917
+ isRefreshable: true,
918
+ PKCEMethod: "S256",
919
+ profileRequest: {
920
+ authIn: "header",
921
+ encoding: "application/json",
922
+ method: "GET",
923
+ url: "https://api.line.me/v2/profile"
924
+ },
925
+ scopeRequired: true,
926
+ subject: ["id"],
927
+ subjectType: "string",
928
+ tokenRequest: {
929
+ authIn: "body",
930
+ encoding: "application/x-www-form-urlencoded",
931
+ url: "https://api.line.me/oauth2/v2.1/token"
932
+ }
933
+ },
934
+ linear: {
935
+ authorizationUrl: "https://linear.app/oauth/authorize",
936
+ isOIDC: false,
937
+ isRefreshable: false,
938
+ profileRequest: {
939
+ authIn: "header",
940
+ body: {
941
+ query: `query { viewer { id name } }`
942
+ },
943
+ encoding: "application/json",
944
+ headers: {
945
+ Accept: "application/json",
946
+ "Content-Type": "application/json"
947
+ },
948
+ method: "POST",
949
+ url: "https://api.linear.app/graphql"
950
+ },
951
+ revocationRequest: {
952
+ authIn: "header",
953
+ encoding: "application/json",
954
+ url: "https://api.linear.app/oauth/revoke"
955
+ },
956
+ scopeRequired: false,
957
+ subject: ["data", "viewer", "id"],
958
+ subjectType: "string",
959
+ tokenRequest: {
960
+ authIn: "body",
961
+ encoding: "application/x-www-form-urlencoded",
962
+ url: "https://api.linear.app/oauth/token"
963
+ }
964
+ },
965
+ linkedin: {
966
+ authorizationUrl: "https://www.linkedin.com/oauth/v2/authorization",
967
+ isOIDC: true,
968
+ isRefreshable: true,
969
+ PKCEMethod: "S256",
970
+ profileRequest: {
971
+ authIn: "header",
972
+ encoding: "application/json",
973
+ method: "GET",
974
+ url: "https://api.linkedin.com/v2/me"
975
+ },
976
+ scopeRequired: true,
977
+ subject: ["id"],
978
+ subjectType: "string",
979
+ tokenRequest: {
980
+ authIn: "body",
981
+ encoding: "application/x-www-form-urlencoded",
982
+ url: "https://www.linkedin.com/oauth/v2/accessToken"
983
+ }
984
+ },
985
+ mastodon: {
986
+ authorizationUrl: (config) => `${config.baseURL}/oauth/authorize`,
987
+ isOIDC: false,
988
+ isRefreshable: false,
989
+ picture: ["avatar"],
990
+ PKCEMethod: "S256",
991
+ profileRequest: {
992
+ authIn: "header",
993
+ encoding: "application/json",
994
+ method: "GET",
995
+ url: (config) => `${config.baseURL}/api/v1/accounts/verify_credentials`
996
+ },
997
+ revocationRequest: {
998
+ authIn: "body",
999
+ encoding: "application/json",
1000
+ tokenParamName: "token",
1001
+ url: (config) => `${config.baseURL}/oauth/revoke`
1002
+ },
1003
+ scopeRequired: false,
1004
+ subject: ["id"],
1005
+ subjectType: "string",
1006
+ tokenRequest: {
1007
+ authIn: "body",
1008
+ encoding: "application/x-www-form-urlencoded",
1009
+ url: (config) => `${config.baseURL}/oauth/token`
1010
+ }
1011
+ },
1012
+ mercadolibre: {
1013
+ authorizationUrl: "https://auth.mercadolibre.com/authorization",
1014
+ isOIDC: false,
1015
+ isRefreshable: true,
1016
+ PKCEMethod: "S256",
1017
+ profileRequest: {
1018
+ authIn: "header",
1019
+ encoding: "application/json",
1020
+ method: "GET",
1021
+ url: "https://api.mercadolibre.com/users/me"
1022
+ },
1023
+ scopeRequired: false,
1024
+ subject: ["id"],
1025
+ subjectType: "number",
1026
+ tokenRequest: {
1027
+ authIn: "body",
1028
+ encoding: "application/x-www-form-urlencoded",
1029
+ url: "https://api.mercadolibre.com/oauth/token"
1030
+ }
1031
+ },
1032
+ mercadopago: {
1033
+ authorizationUrl: "https://auth.mercadopago.com/authorization",
1034
+ isOIDC: false,
1035
+ isRefreshable: true,
1036
+ profileRequest: {
1037
+ authIn: "header",
1038
+ encoding: "application/json",
1039
+ method: "GET",
1040
+ url: "https://api.mercadopago.com/v1/users/me"
1041
+ },
1042
+ scopeRequired: false,
1043
+ subject: ["id"],
1044
+ subjectType: "number",
1045
+ tokenRequest: {
1046
+ authIn: "body",
1047
+ encoding: "application/x-www-form-urlencoded",
1048
+ url: "https://api.mercadopago.com/oauth/token"
1049
+ }
1050
+ },
1051
+ microsoftentraid: {
1052
+ authorizationUrl: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/oauth2/v2.0/authorize`,
1053
+ isOIDC: true,
1054
+ isRefreshable: true,
1055
+ PKCEMethod: "S256",
1056
+ profileRequest: {
1057
+ authIn: "header",
1058
+ encoding: "application/json",
1059
+ method: "GET",
1060
+ url: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/openid/userinfo`
1061
+ },
1062
+ scopeRequired: false,
1063
+ subject: ["id"],
1064
+ subjectType: "string",
1065
+ tokenRequest: {
1066
+ authIn: "body",
1067
+ encoding: "application/x-www-form-urlencoded",
1068
+ url: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/oauth2/v2.0/token`
1069
+ }
1070
+ },
1071
+ monday: {
1072
+ authorizationUrl: "https://auth.monday.com/oauth2/authorize",
1073
+ isOIDC: false,
1074
+ isRefreshable: true,
1075
+ profileRequest: {
1076
+ authIn: "header",
1077
+ body: {
1078
+ query: "query { me { id name email } }"
1079
+ },
1080
+ encoding: "application/json",
1081
+ headers: {
1082
+ "Content-Type": "application/json"
1083
+ },
1084
+ method: "POST",
1085
+ url: "https://api.monday.com/v2"
1086
+ },
1087
+ scopeRequired: true,
1088
+ subject: ["data", "me", "id"],
1089
+ subjectType: "number",
1090
+ tokenRequest: {
1091
+ authIn: "body",
1092
+ encoding: "application/x-www-form-urlencoded",
1093
+ url: "https://auth.monday.com/oauth2/token"
1094
+ }
1095
+ },
1096
+ myanimelist: {
1097
+ authorizationUrl: "https://myanimelist.net/v1/oauth2/authorize",
1098
+ isOIDC: false,
1099
+ isRefreshable: true,
1100
+ PKCEMethod: "plain",
1101
+ profileRequest: {
1102
+ authIn: "header",
1103
+ encoding: "application/json",
1104
+ method: "GET",
1105
+ url: "https://api.myanimelist.net/v2/users/@me"
1106
+ },
1107
+ scopeRequired: false,
1108
+ subject: ["id"],
1109
+ subjectType: "number",
1110
+ tokenRequest: {
1111
+ authIn: "body",
1112
+ encoding: "application/x-www-form-urlencoded",
1113
+ url: "https://myanimelist.net/v1/oauth2/token"
1114
+ }
1115
+ },
1116
+ naver: {
1117
+ authorizationUrl: "https://nid.naver.com/oauth2.0/authorize",
1118
+ email: ["response", "email"],
1119
+ fullName: ["response", "name"],
1120
+ isOIDC: false,
1121
+ isRefreshable: true,
1122
+ picture: ["response", "profile_image"],
1123
+ profileRequest: {
1124
+ authIn: "header",
1125
+ encoding: "application/json",
1126
+ method: "GET",
1127
+ url: "https://openapi.naver.com/v1/nid/me"
1128
+ },
1129
+ scopeRequired: false,
1130
+ subject: ["response", "id"],
1131
+ subjectType: "string",
1132
+ tokenRequest: {
1133
+ authIn: "body",
1134
+ encoding: "application/x-www-form-urlencoded",
1135
+ url: "https://nid.naver.com/oauth2.0/token"
1136
+ }
1137
+ },
1138
+ notion: {
1139
+ authorizationUrl: "https://api.notion.com/v1/oauth/authorize",
1140
+ email: ["bot", "owner", "user", "person", "email"],
1141
+ isOIDC: false,
1142
+ isRefreshable: false,
1143
+ picture: ["bot", "owner", "user", "avatar_url"],
1144
+ profileRequest: {
1145
+ authIn: "header",
1146
+ encoding: "application/json",
1147
+ headers: {
1148
+ "Notion-Version": "2022-06-28"
1149
+ },
1150
+ method: "GET",
1151
+ url: "https://api.notion.com/v1/users/me"
1152
+ },
1153
+ scopeRequired: false,
1154
+ subject: ["bot", "owner", "user", "id"],
1155
+ subjectType: "string",
1156
+ tokenRequest: {
1157
+ authIn: "header",
1158
+ encoding: "application/json",
1159
+ url: "https://api.notion.com/v1/oauth/token"
1160
+ }
1161
+ },
1162
+ okta: {
1163
+ authorizationUrl: (config) => `https://${config.domain}/oauth2/default/v1/authorize`,
1164
+ isOIDC: true,
1165
+ isRefreshable: true,
1166
+ PKCEMethod: "S256",
1167
+ profileRequest: {
1168
+ authIn: "header",
1169
+ encoding: "application/json",
1170
+ method: "GET",
1171
+ url: (config) => `https://${config.domain}/oauth2/default/v1/userinfo`
1172
+ },
1173
+ revocationRequest: {
1174
+ authIn: "body",
1175
+ encoding: "application/json",
1176
+ tokenParamName: "token",
1177
+ url: (config) => `https://${config.domain}/oauth2/default/v1/revoke`
1178
+ },
1179
+ scopeRequired: true,
1180
+ subject: ["id"],
1181
+ subjectType: "string",
1182
+ tokenRequest: {
1183
+ authIn: "body",
1184
+ encoding: "application/x-www-form-urlencoded",
1185
+ url: (config) => `https://${config.domain}/oauth2/default/v1/token`
1186
+ }
1187
+ },
1188
+ osu: {
1189
+ authorizationUrl: "https://osu.ppy.sh/oauth/authorize",
1190
+ isOIDC: false,
1191
+ isRefreshable: true,
1192
+ picture: ["avatar_url"],
1193
+ profileRequest: {
1194
+ authIn: "header",
1195
+ encoding: "application/json",
1196
+ method: "GET",
1197
+ url: "https://osu.ppy.sh/api/v2/me"
1198
+ },
1199
+ scopeRequired: false,
1200
+ subject: ["id"],
1201
+ subjectType: "number",
1202
+ tokenRequest: {
1203
+ authIn: "body",
1204
+ encoding: "application/x-www-form-urlencoded",
1205
+ url: "https://osu.ppy.sh/oauth/token"
1206
+ }
1207
+ },
1208
+ patreon: {
1209
+ authorizationUrl: "https://www.patreon.com/oauth2/authorize",
1210
+ isOIDC: false,
1211
+ isRefreshable: true,
1212
+ profileRequest: {
1213
+ authIn: "header",
1214
+ encoding: "application/json",
1215
+ method: "GET",
1216
+ url: "https://www.patreon.com/api/oauth2/v2/identity"
1217
+ },
1218
+ scopeRequired: false,
1219
+ subject: ["data", "id"],
1220
+ subjectType: "string",
1221
+ tokenRequest: {
1222
+ authIn: "body",
1223
+ encoding: "application/x-www-form-urlencoded",
1224
+ url: "https://www.patreon.com/api/oauth2/token"
1225
+ }
1226
+ },
1227
+ pipedrive: {
1228
+ authorizationUrl: "https://oauth.pipedrive.com/oauth/authorize",
1229
+ isOIDC: false,
1230
+ isRefreshable: true,
1231
+ profileRequest: {
1232
+ authIn: "header",
1233
+ encoding: "application/json",
1234
+ method: "GET",
1235
+ url: "https://api.pipedrive.com/v1/users/me"
1236
+ },
1237
+ scopeRequired: true,
1238
+ subject: ["data", "id"],
1239
+ subjectType: "number",
1240
+ tokenRequest: {
1241
+ authIn: "body",
1242
+ encoding: "application/x-www-form-urlencoded",
1243
+ url: "https://oauth.pipedrive.com/oauth/token"
1244
+ }
1245
+ },
1246
+ polar: {
1247
+ authorizationUrl: "https://polar.sh/oauth2/authorize",
1248
+ isOIDC: true,
1249
+ isRefreshable: true,
1250
+ PKCEMethod: "S256",
1251
+ profileRequest: {
1252
+ authIn: "header",
1253
+ encoding: "application/json",
1254
+ method: "GET",
1255
+ url: "https://api.polar.sh/v1/oauth2/userinfo"
1256
+ },
1257
+ revocationRequest: {
1258
+ authIn: "body",
1259
+ encoding: "application/json",
1260
+ tokenParamName: "token",
1261
+ url: "https://api.polar.sh/v1/oauth2/revoke"
1262
+ },
1263
+ scopeRequired: true,
1264
+ subject: ["id"],
1265
+ subjectType: "string",
1266
+ tokenRequest: {
1267
+ authIn: "body",
1268
+ encoding: "application/x-www-form-urlencoded",
1269
+ url: "https://api.polar.sh/v1/oauth2/token"
1270
+ }
1271
+ },
1272
+ polaraccesslink: {
1273
+ authorizationUrl: "https://flow.polar.com/oauth2/authorization",
1274
+ isOIDC: false,
1275
+ isRefreshable: false,
1276
+ PKCEMethod: "S256",
1277
+ profileRequest: {
1278
+ authIn: "header",
1279
+ encoding: "application/json",
1280
+ method: "GET",
1281
+ url: "https://www.polaraccesslink.com/v3/users/me"
1282
+ },
1283
+ scopeRequired: false,
1284
+ subject: ["x_user_id"],
1285
+ subjectType: "number",
1286
+ tokenRequest: {
1287
+ authIn: "header",
1288
+ encoding: "application/x-www-form-urlencoded",
1289
+ url: "https://polarremote.com/v2/oauth2/token"
1290
+ }
1291
+ },
1292
+ polarteampro: {
1293
+ authorizationUrl: "https://auth.polar.com/oauth/authorize",
1294
+ isOIDC: false,
1295
+ isRefreshable: true,
1296
+ PKCEMethod: "S256",
1297
+ profileRequest: {
1298
+ authIn: "header",
1299
+ encoding: "application/json",
1300
+ method: "GET",
1301
+ url: "https://www.polaraccesslink.com/v3/users/<USER_ID>"
1302
+ },
1303
+ scopeRequired: false,
1304
+ subject: ["x_user_id"],
1305
+ subjectType: "number",
1306
+ tokenRequest: {
1307
+ authIn: "header",
1308
+ encoding: "application/x-www-form-urlencoded",
1309
+ url: "https://auth.polar.com/oauth/token"
1310
+ }
1311
+ },
1312
+ reddit: {
1313
+ authorizationUrl: "https://www.reddit.com/api/v1/authorize",
1314
+ isOIDC: false,
1315
+ isRefreshable: true,
1316
+ profileRequest: {
1317
+ authIn: "header",
1318
+ encoding: "application/json",
1319
+ method: "GET",
1320
+ url: "https://oauth.reddit.com/api/v1/me"
1321
+ },
1322
+ revocationRequest: {
1323
+ authIn: "header",
1324
+ body: new URLSearchParams({
1325
+ token_type_hint: "refresh_token"
1326
+ }),
1327
+ encoding: "application/json",
1328
+ url: "https://www.reddit.com/api/v1/revoke_token"
1329
+ },
1330
+ scopeRequired: true,
1331
+ subject: ["id"],
1332
+ subjectType: "string",
1333
+ tokenRequest: {
1334
+ authIn: "header",
1335
+ encoding: "application/x-www-form-urlencoded",
1336
+ url: "https://www.reddit.com/api/v1/access_token"
1337
+ }
1338
+ },
1339
+ roblox: {
1340
+ authorizationUrl: "https://apis.roblox.com/oauth/v1/authorize",
1341
+ isOIDC: true,
1342
+ isRefreshable: true,
1343
+ picture: ["picture"],
1344
+ PKCEMethod: "S256",
1345
+ profileRequest: {
1346
+ authIn: "header",
1347
+ encoding: "application/json",
1348
+ method: "GET",
1349
+ url: "https://apis.roblox.com/oauth/v1/userinfo"
1350
+ },
1351
+ scopeRequired: true,
1352
+ subject: ["id"],
1353
+ subjectType: "string",
1354
+ tokenRequest: {
1355
+ authIn: "body",
1356
+ encoding: "application/x-www-form-urlencoded",
1357
+ url: "https://apis.roblox.com/oauth/v1/token"
1358
+ }
1359
+ },
1360
+ salesforce: {
1361
+ authorizationUrl: "https://login.salesforce.com/services/oauth2/authorize",
1362
+ isOIDC: true,
1363
+ isRefreshable: true,
1364
+ PKCEMethod: "S256",
1365
+ profileRequest: {
1366
+ authIn: "header",
1367
+ encoding: "application/json",
1368
+ method: "GET",
1369
+ url: "https://login.salesforce.com/services/oauth2/userinfo"
1370
+ },
1371
+ revocationRequest: {
1372
+ authIn: "header",
1373
+ encoding: "application/json",
1374
+ url: "https://login.salesforce.com/services/oauth2/revoke"
1375
+ },
1376
+ scopeRequired: false,
1377
+ subject: ["id"],
1378
+ subjectType: "string",
1379
+ tokenRequest: {
1380
+ authIn: "body",
1381
+ encoding: "application/x-www-form-urlencoded",
1382
+ url: "https://login.salesforce.com/services/oauth2/token"
1383
+ }
1384
+ },
1385
+ shikimori: {
1386
+ authorizationUrl: "https://shikimori.org/oauth/authorize",
1387
+ isOIDC: false,
1388
+ isRefreshable: true,
1389
+ profileRequest: {
1390
+ authIn: "header",
1391
+ encoding: "application/json",
1392
+ method: "GET",
1393
+ url: "https://shikimori.one/api/users/whoami"
1394
+ },
1395
+ scopeRequired: false,
1396
+ subject: ["id"],
1397
+ subjectType: "number",
1398
+ tokenRequest: {
1399
+ authIn: "body",
1400
+ encoding: "application/x-www-form-urlencoded",
1401
+ url: "https://shikimori.org/oauth/token"
1402
+ }
1403
+ },
1404
+ slack: {
1405
+ authorizationUrl: "https://slack.com/openid/connect/authorize",
1406
+ isOIDC: true,
1407
+ isRefreshable: true,
1408
+ profileRequest: {
1409
+ authIn: "query",
1410
+ encoding: "application/json",
1411
+ method: "GET",
1412
+ url: "https://slack.com/api/users.identity"
1413
+ },
1414
+ revocationRequest: {
1415
+ authIn: "body",
1416
+ encoding: "application/json",
1417
+ tokenParamName: "token",
1418
+ url: "https://slack.com/api/auth.revoke"
1419
+ },
1420
+ scopeRequired: true,
1421
+ subject: ["id"],
1422
+ subjectType: "string",
1423
+ tokenRequest: {
1424
+ authIn: "body",
1425
+ encoding: "application/x-www-form-urlencoded",
1426
+ url: "https://slack.com/api/openid.connect.token"
1427
+ }
1428
+ },
1429
+ spotify: {
1430
+ authorizationUrl: "https://accounts.spotify.com/authorize",
1431
+ isOIDC: false,
1432
+ isRefreshable: true,
1433
+ PKCEMethod: "S256",
1434
+ profileRequest: {
1435
+ authIn: "header",
1436
+ encoding: "application/json",
1437
+ method: "GET",
1438
+ url: "https://api.spotify.com/v1/me"
1439
+ },
1440
+ scopeRequired: false,
1441
+ subject: ["id"],
1442
+ subjectType: "string",
1443
+ tokenRequest: {
1444
+ authIn: "body",
1445
+ encoding: "application/x-www-form-urlencoded",
1446
+ url: "https://accounts.spotify.com/api/token"
1447
+ }
1448
+ },
1449
+ startgg: {
1450
+ authorizationUrl: "https://start.gg/oauth/authorize",
1451
+ email: ["data", "currentUser", "email"],
1452
+ isOIDC: false,
1453
+ isRefreshable: true,
1454
+ profileRequest: {
1455
+ authIn: "header",
1456
+ body: {
1457
+ query: `query { currentUser { id slug email player { gamerTag } } }`
1458
+ },
1459
+ encoding: "application/json",
1460
+ headers: {
1461
+ Accept: "application/json",
1462
+ "Content-Type": "application/json"
1463
+ },
1464
+ method: "POST",
1465
+ url: "https://api.start.gg/gql/alpha"
1466
+ },
1467
+ scopeRequired: false,
1468
+ subject: ["data", "currentUser", "id"],
1469
+ subjectType: "number",
1470
+ tokenRequest: {
1471
+ authIn: "body",
1472
+ encoding: "application/x-www-form-urlencoded",
1473
+ url: "https://api.start.gg/oauth/access_token"
1474
+ }
1475
+ },
1476
+ strava: {
1477
+ authorizationUrl: "https://www.strava.com/oauth/authorize",
1478
+ familyName: ["lastname"],
1479
+ givenName: ["firstname"],
1480
+ isOIDC: false,
1481
+ isRefreshable: true,
1482
+ picture: ["profile"],
1483
+ PKCEMethod: "S256",
1484
+ profileRequest: {
1485
+ authIn: "header",
1486
+ encoding: "application/json",
1487
+ method: "GET",
1488
+ url: "https://www.strava.com/api/v3/athlete"
1489
+ },
1490
+ revocationRequest: {
1491
+ authIn: "query",
1492
+ body: new URLSearchParams({
1493
+ token_type_hint: "access_token"
1494
+ }),
1495
+ encoding: "application/json",
1496
+ tokenParamName: "access_token",
1497
+ url: "https://www.strava.com/oauth/deauthorize"
1498
+ },
1499
+ scopeRequired: false,
1500
+ subject: ["id"],
1501
+ subjectType: "number",
1502
+ tokenRequest: {
1503
+ authIn: "body",
1504
+ encoding: "application/x-www-form-urlencoded",
1505
+ url: "https://www.strava.com/oauth/token"
1506
+ }
1507
+ },
1508
+ synology: {
1509
+ authorizationUrl: (config) => `${config.baseURL}/webman/sso/SSOOauth.cgi?client_id=${config.clientId}&response_type=code&redirect_uri=${config.redirectUri}`,
1510
+ isOIDC: false,
1511
+ isRefreshable: false,
1512
+ profileRequest: {
1513
+ authIn: "header",
1514
+ encoding: "application/json",
1515
+ method: "GET",
1516
+ url: (config) => `${config.baseURL}/webman/sso/SSOUserInfo.cgi?client_id=${config.clientId}&access_token=${config.accessToken}`
1517
+ },
1518
+ scopeRequired: false,
1519
+ subject: ["data", "id"],
1520
+ subjectType: "number",
1521
+ tokenRequest: {
1522
+ authIn: "body",
1523
+ encoding: "application/x-www-form-urlencoded",
1524
+ url: (config) => `${config.baseURL}/webman/sso/SSOAccessToken.cgi?client_id=${config.clientId}&client_secret=${config.clientSecret}`
1525
+ }
1526
+ },
1527
+ tiktok: {
1528
+ authorizationUrl: "https://www.tiktok.com/v2/auth/authorize",
1529
+ createAuthorizationURLSearchParams: (config) => ({
1530
+ client_key: config.clientId
1531
+ }),
1532
+ isOIDC: false,
1533
+ isRefreshable: true,
1534
+ PKCEMethod: "S256",
1535
+ profileRequest: {
1536
+ authIn: "query",
1537
+ encoding: "application/json",
1538
+ method: "GET",
1539
+ url: "https://open.douyin.com/oauth/userinfo"
1540
+ },
1541
+ revocationRequest: {
1542
+ authIn: "body",
1543
+ encoding: "application/json",
1544
+ tokenParamName: "token",
1545
+ url: "https://open.tiktokapis.com/v2/oauth/revoke/"
1546
+ },
1547
+ scopeRequired: false,
1548
+ subject: ["data", "open_id"],
1549
+ subjectType: "string",
1550
+ tokenRequest: {
1551
+ authIn: "body",
1552
+ encoding: "application/x-www-form-urlencoded",
1553
+ url: "https://open.tiktokapis.com/v2/oauth/token/"
1554
+ }
1555
+ },
1556
+ tiltify: {
1557
+ authorizationUrl: "https://v5api.tiltify.com/oauth/authorize",
1558
+ isOIDC: false,
1559
+ isRefreshable: true,
1560
+ profileRequest: {
1561
+ authIn: "header",
1562
+ encoding: "application/json",
1563
+ method: "GET",
1564
+ url: "https://v5api.tiltify.com/api/public/current-user"
1565
+ },
1566
+ scopeRequired: false,
1567
+ subject: ["data", "id"],
1568
+ subjectType: "string",
1569
+ tokenRequest: {
1570
+ authIn: "body",
1571
+ encoding: "application/x-www-form-urlencoded",
1572
+ url: "https://v5api.tiltify.com/oauth/token"
1573
+ }
1574
+ },
1575
+ tumblr: {
1576
+ authorizationUrl: "https://www.tumblr.com/oauth2/authorize",
1577
+ isOIDC: false,
1578
+ isRefreshable: true,
1579
+ profileRequest: {
1580
+ authIn: "header",
1581
+ encoding: "application/json",
1582
+ method: "GET",
1583
+ url: "https://api.tumblr.com/v2/user/info"
1584
+ },
1585
+ scopeRequired: false,
1586
+ subject: ["response", "user", "name"],
1587
+ subjectType: "string",
1588
+ tokenRequest: {
1589
+ authIn: "body",
1590
+ encoding: "application/x-www-form-urlencoded",
1591
+ url: "https://api.tumblr.com/v2/oauth2/token"
1592
+ }
1593
+ },
1594
+ twitch: {
1595
+ authorizationUrl: "https://id.twitch.tv/oauth2/authorize",
1596
+ isOIDC: true,
1597
+ isRefreshable: true,
1598
+ profileRequest: {
1599
+ authIn: "header",
1600
+ encoding: "application/json",
1601
+ headers: (config) => ({
1602
+ "Client-Id": config.clientId
1603
+ }),
1604
+ method: "GET",
1605
+ url: "https://api.twitch.tv/helix/users"
1606
+ },
1607
+ revocationRequest: {
1608
+ authIn: "query",
1609
+ encoding: "application/json",
1610
+ headers: (config) => ({
1611
+ "Client-Id": config.clientId
1612
+ }),
1613
+ tokenParamName: "token",
1614
+ url: "https://id.twitch.tv/oauth2/revoke"
1615
+ },
1616
+ scopeRequired: false,
1617
+ subject: ["id"],
1618
+ subjectType: "string",
1619
+ tokenRequest: {
1620
+ authIn: "body",
1621
+ encoding: "application/x-www-form-urlencoded",
1622
+ url: "https://id.twitch.tv/oauth2/token"
1623
+ }
1624
+ },
1625
+ twitter: {
1626
+ authorizationUrl: "https://twitter.com/i/oauth2/authorize",
1627
+ isOIDC: false,
1628
+ isRefreshable: true,
1629
+ PKCEMethod: "S256",
1630
+ profileRequest: {
1631
+ authIn: "header",
1632
+ encoding: "application/json",
1633
+ method: "GET",
1634
+ url: "https://api.twitter.com/2/users/me"
1635
+ },
1636
+ revocationRequest: {
1637
+ authIn: "header",
1638
+ encoding: "application/json",
1639
+ url: "https://api.twitter.com/2/oauth2/revoke"
1640
+ },
1641
+ scopeRequired: false,
1642
+ subject: ["data", "id"],
1643
+ subjectType: "number",
1644
+ tokenRequest: {
1645
+ authIn: "body",
1646
+ encoding: "application/x-www-form-urlencoded",
1647
+ url: "https://api.twitter.com/2/oauth2/token"
1648
+ }
1649
+ },
1650
+ vk: {
1651
+ authorizationUrl: "https://oauth.vk.com/authorize",
1652
+ isOIDC: false,
1653
+ isRefreshable: false,
1654
+ profileRequest: {
1655
+ authIn: "query",
1656
+ encoding: "application/json",
1657
+ method: "GET",
1658
+ url: "https://api.vk.com/method/users.get"
1659
+ },
1660
+ scopeRequired: false,
1661
+ subject: ["response", "0", "id"],
1662
+ subjectType: "number",
1663
+ tokenRequest: {
1664
+ authIn: "body",
1665
+ encoding: "application/x-www-form-urlencoded",
1666
+ url: "https://oauth.vk.com/access_token"
1667
+ }
1668
+ },
1669
+ withings: {
1670
+ authorizationUrl: "https://account.withings.com/oauth2_user/authorize2",
1671
+ isOIDC: false,
1672
+ isRefreshable: true,
1673
+ profileRequest: {
1674
+ authIn: "header",
1675
+ body: async (config) => {
1676
+ const props = await getWithingsProps(config);
1677
+ if (props === undefined)
1678
+ throw new Error("Failed to get Withings search properties");
1679
+ const { nonce, hashedSignature } = props;
1680
+ return [
1681
+ ["action", "getuser"],
1682
+ ["nonce", nonce],
1683
+ ["client_id", config.clientId],
1684
+ ["signature", hashedSignature]
1685
+ ];
1686
+ },
1687
+ encoding: "application/x-www-form-urlencoded",
1688
+ method: "POST",
1689
+ url: "https://wbsapi.withings.net/v2/oauth2"
1690
+ },
1691
+ refreshAccessTokenBody: {
1692
+ action: "requesttoken"
1693
+ },
1694
+ revocationRequest: {
1695
+ authIn: "header",
1696
+ body: async (config) => {
1697
+ const props = await getWithingsProps(config);
1698
+ if (!props)
1699
+ throw new Error("Failed to get Withings props");
1700
+ const { nonce, hashedSignature } = props;
1701
+ return [
1702
+ ["action", "revoke"],
1703
+ ["client_id", config.clientId],
1704
+ ["nonce", nonce],
1705
+ ["signature", hashedSignature]
1706
+ ];
1707
+ },
1708
+ encoding: "application/x-www-form-urlencoded",
1709
+ method: "POST",
1710
+ url: "https://wbsapi.withings.net/v2/oauth2"
1711
+ },
1712
+ scopeRequired: true,
1713
+ subject: ["userid"],
1714
+ subjectType: "string",
1715
+ tokenRequest: {
1716
+ authIn: "body",
1717
+ encoding: "application/x-www-form-urlencoded",
1718
+ url: "https://wbsapi.withings.net/v2/oauth2"
1719
+ },
1720
+ validateAuthorizationCodeBody: {
1721
+ action: "requesttoken"
1722
+ }
1723
+ },
1724
+ workos: {
1725
+ authorizationUrl: (config) => `https://${config.domain}/oauth2/authorize`,
1726
+ createAuthorizationURLSearchParams: () => {
1727
+ const nonce = crypto.randomUUID();
1728
+ return {
1729
+ nonce
1730
+ };
1731
+ },
1732
+ email: ["email"],
1733
+ familyName: ["family_name"],
1734
+ fullName: ["name"],
1735
+ givenName: ["given_name"],
1736
+ isOIDC: true,
1737
+ isRefreshable: true,
1738
+ PKCEMethod: "S256",
1739
+ profileRequest: {
1740
+ authIn: "header",
1741
+ encoding: "application/json",
1742
+ method: "POST",
1743
+ url: (config) => `https://${config.domain}/oauth2/userinfo`
1744
+ },
1745
+ scopeRequired: false,
1746
+ subject: ["id"],
1747
+ subjectType: "string",
1748
+ tokenRequest: {
1749
+ authIn: "body",
1750
+ encoding: "application/x-www-form-urlencoded",
1751
+ url: (config) => `https://${config.domain}/oauth2/token`
1752
+ }
1753
+ },
1754
+ yahoo: {
1755
+ authorizationUrl: "https://api.login.yahoo.com/oauth2/request_auth",
1756
+ isOIDC: true,
1757
+ isRefreshable: true,
1758
+ PKCEMethod: "S256",
1759
+ profileRequest: {
1760
+ authIn: "header",
1761
+ encoding: "application/json",
1762
+ method: "GET",
1763
+ url: "https://api.login.yahoo.com/openid/v1/userinfo"
1764
+ },
1765
+ revocationRequest: {
1766
+ authIn: "header",
1767
+ encoding: "application/json",
1768
+ url: "https://api.login.yahoo.com/oauth2/revoke"
1769
+ },
1770
+ scopeRequired: false,
1771
+ subject: ["id"],
1772
+ subjectType: "string",
1773
+ tokenRequest: {
1774
+ authIn: "body",
1775
+ encoding: "application/x-www-form-urlencoded",
1776
+ url: "https://api.login.yahoo.com/oauth2/get_token"
1777
+ }
1778
+ },
1779
+ yandex: {
1780
+ authorizationUrl: "https://oauth.yandex.com/authorize",
1781
+ createAuthorizationURLSearchParams: {
1782
+ device_id: crypto.randomUUID(),
1783
+ device_name: `${navigator.platform ?? "Unknown"} \u2014 ${(navigator.userAgent.split(")")[0] || "").split("(").pop() || "Unknown"}`
1784
+ },
1785
+ email: ["default_email"],
1786
+ familyName: ["last_name"],
1787
+ fullName: ["real_name"],
1788
+ givenName: ["first_name"],
1789
+ isOIDC: false,
1790
+ isRefreshable: true,
1791
+ PKCEMethod: "S256",
1792
+ profileRequest: {
1793
+ authIn: "header",
1794
+ encoding: "application/json",
1795
+ method: "GET",
1796
+ url: "https://login.yandex.ru/info"
1797
+ },
1798
+ revocationRequest: {
1799
+ authIn: "body",
1800
+ encoding: "application/json",
1801
+ tokenParamName: "access_token",
1802
+ url: "https://oauth.yandex.com/revoke_token"
1803
+ },
1804
+ scopeRequired: false,
1805
+ subject: ["id"],
1806
+ subjectType: "string",
1807
+ tokenRequest: {
1808
+ authIn: "body",
1809
+ encoding: "application/x-www-form-urlencoded",
1810
+ url: "https://oauth.yandex.com/token"
1811
+ }
1812
+ },
1813
+ zoho: {
1814
+ authorizationUrl: (config) => `https://accounts.zoho.${config.region ?? "com"}/oauth/v2/auth`,
1815
+ isOIDC: false,
1816
+ isRefreshable: true,
1817
+ PKCEMethod: "S256",
1818
+ profileRequest: {
1819
+ authIn: "header",
1820
+ encoding: "application/json",
1821
+ method: "GET",
1822
+ url: (config) => `https://accounts.zoho.${config.region ?? "com"}/oauth/user/info`
1823
+ },
1824
+ revocationRequest: {
1825
+ authIn: "query",
1826
+ encoding: "application/x-www-form-urlencoded",
1827
+ tokenParamName: "token",
1828
+ url: (config) => `https://accounts.zoho.${config.region ?? "com"}/oauth/v2/token/revoke`
1829
+ },
1830
+ scopeRequired: true,
1831
+ subject: ["ZUID"],
1832
+ subjectType: "string",
1833
+ tokenRequest: {
1834
+ authIn: "body",
1835
+ encoding: "application/x-www-form-urlencoded",
1836
+ url: (config) => `https://accounts.zoho.${config.region ?? "com"}/oauth/v2/token`
1837
+ }
1838
+ },
1839
+ zoom: {
1840
+ authorizationUrl: "https://zoom.us/oauth/authorize",
1841
+ email: ["email"],
1842
+ familyName: ["last_name"],
1843
+ givenName: ["first_name"],
1844
+ isOIDC: false,
1845
+ isRefreshable: true,
1846
+ picture: ["pic_url"],
1847
+ PKCEMethod: "S256",
1848
+ profileRequest: {
1849
+ authIn: "header",
1850
+ encoding: "application/json",
1851
+ method: "GET",
1852
+ url: "https://api.zoom.us/v2/users/me"
1853
+ },
1854
+ revocationRequest: {
1855
+ authIn: "query",
1856
+ encoding: "application/json",
1857
+ headers: (config) => ({
1858
+ Authorization: `Basic ${btoa(`${config.clientId}:${config.clientSecret}`)}`
1859
+ }),
1860
+ tokenParamName: "token",
1861
+ url: "https://zoom.us/oauth/revoke"
1862
+ },
1863
+ scopeRequired: false,
1864
+ subject: ["id"],
1865
+ subjectType: "string",
1866
+ tokenRequest: {
1867
+ authIn: "body",
1868
+ encoding: "application/x-www-form-urlencoded",
1869
+ url: "https://zoom.us/oauth/token"
1870
+ }
1871
+ }
1872
+ });
1873
+ var hasClientSecret = (credentials) => {
1874
+ if (typeof credentials !== "object" || credentials === null)
1875
+ return false;
1876
+ const secret = Reflect.get(credentials, "clientSecret");
1877
+ return typeof secret === "string";
1878
+ };
1879
+ var isExpectedType = (value, kind) => {
1880
+ switch (kind) {
1881
+ case "string":
1882
+ return typeof value === "string";
1883
+ case "number":
1884
+ return typeof value === "number";
1885
+ case "boolean":
1886
+ return typeof value === "boolean";
1887
+ case "object":
1888
+ return typeof value === "object" && value !== null;
1889
+ default:
1890
+ return false;
1891
+ }
1892
+ };
1893
+ var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
1894
+ var isOIDCProviderOption = (option) => {
1895
+ if (!isValidProviderOption(option))
1896
+ return false;
1897
+ const provider = providers[option];
1898
+ return provider.isOIDC;
1899
+ };
1900
+ var isPKCEProviderOption = (option) => {
1901
+ if (!isValidProviderOption(option))
1902
+ return false;
1903
+ const provider = providers[option];
1904
+ return provider.PKCEMethod !== undefined;
1905
+ };
1906
+ var isRefreshableOAuth2Client = (providerName, _client) => isRefreshableProviderOption(providerName);
1907
+ var isRefreshableProviderOption = (option) => {
1908
+ if (!isValidProviderOption(option))
1909
+ return false;
1910
+ const provider = providers[option];
1911
+ return provider.isRefreshable;
1912
+ };
1913
+ var isRevocableOAuth2Client = (providerName, _client) => isRevocableProviderOption(providerName);
1914
+ var isRevocableProviderOption = (option) => {
1915
+ if (!isValidProviderOption(option))
1916
+ return false;
1917
+ const provider = providers[option];
1918
+ return provider.revocationRequest !== undefined;
1919
+ };
1920
+ var isScopeRequiredProviderOption = (option) => {
1921
+ if (!isValidProviderOption(option))
1922
+ return false;
1923
+ const provider = providers[option];
1924
+ return provider.scopeRequired;
1925
+ };
1926
+ var isValidProviderOption = (option) => Object.hasOwn(providers, option);
1927
+ var createOAuth2FetchError = async (response) => {
1928
+ const clone = response.clone();
1929
+ const prefix = `HTTP ${response.status} ${response.statusText} for ${response.url}`;
1930
+ const payload = await response.json().catch(() => null);
1931
+ if (payload && typeof payload === "object" && Object.keys(payload).length) {
1932
+ return new Error(`${prefix}
1933
+ ${JSON.stringify(payload)}`);
1934
+ }
1935
+ const text = await clone.text().catch(() => "");
1936
+ if (text) {
1937
+ return new Error(`${prefix}
1938
+ ${text}`);
1939
+ }
1940
+ return new Error(prefix);
1941
+ };
1942
+ var createOAuth2Request = ({
1943
+ url,
1944
+ body,
1945
+ authIn,
1946
+ headers,
1947
+ encoding,
1948
+ clientId,
1949
+ clientSecret
1950
+ }) => {
1951
+ const oauthHeaders = new Headers(headers);
1952
+ oauthHeaders.set("Accept", "application/json");
1953
+ oauthHeaders.set("User-Agent", "citra");
1954
+ if (authIn === "header") {
1955
+ if (!clientSecret) {
1956
+ throw new Error("clientSecret required for header auth");
1957
+ }
1958
+ oauthHeaders.set("Authorization", `Basic ${encodeBase64(`${clientId}:${clientSecret}`)}`);
1959
+ }
1960
+ if (encoding === "application/json") {
1961
+ oauthHeaders.set("Content-Type", "application/json");
1962
+ return new Request(url, {
1963
+ body: JSON.stringify(body),
1964
+ headers: oauthHeaders,
1965
+ method: "POST"
1966
+ });
1967
+ }
1968
+ oauthHeaders.set("Content-Type", "application/x-www-form-urlencoded");
1969
+ const entries = body instanceof URLSearchParams ? Array.from(body.entries()) : Object.entries(body).filter((entry) => typeof entry[1] === "string");
1970
+ const params = new URLSearchParams(entries);
1971
+ if (authIn === "body") {
1972
+ params.set("client_id", clientId);
1973
+ clientSecret && params.set("client_secret", clientSecret);
1974
+ }
1975
+ return new Request(url, {
1976
+ body: params.toString(),
1977
+ headers: oauthHeaders,
1978
+ method: "POST"
1979
+ });
1980
+ };
1981
+ var decodeBase64 = (input, toUint8Array = false) => {
1982
+ const b64 = input.replace(/-/g, "+").replace(/_/g, "/") + "==".slice(0, (BASE64_BLOCK_SIZE - input.length % BASE64_BLOCK_SIZE) % BASE64_BLOCK_SIZE);
1983
+ const raw = atob(b64);
1984
+ if (!toUint8Array) {
1985
+ return raw;
1986
+ }
1987
+ const bytes = new Uint8Array(raw.length);
1988
+ for (let i = 0;i < raw.length; i++) {
1989
+ bytes[i] = raw.charCodeAt(i);
1990
+ }
1991
+ return bytes;
1992
+ };
1993
+ var decodeJWT = (tokenString) => {
1994
+ const [headerSegment, payloadSegment, signatureSegment] = tokenString.split(".");
1995
+ if (!headerSegment || !payloadSegment || !signatureSegment) {
1996
+ throw new Error("Invalid JWT format");
1997
+ }
1998
+ const decodedPayload = decodeBase64(payloadSegment);
1999
+ if (typeof decodedPayload !== "string") {
2000
+ throw new Error("Expected JWT payload to be a UTF-8 string");
2001
+ }
2002
+ const claims = JSON.parse(decodedPayload);
2003
+ return claims;
2004
+ };
2005
+ var encodeBase64 = (input) => {
2006
+ let raw;
2007
+ if (typeof input === "string") {
2008
+ raw = input;
2009
+ } else {
2010
+ const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
2011
+ raw = bytes.reduce((acc, byte) => acc + String.fromCharCode(byte), "");
2012
+ }
2013
+ return btoa(raw);
2014
+ };
2015
+ var getWithingsProps = async (config) => {
2016
+ const timestamp = Math.floor(Date.now() / 1000);
2017
+ const signature = `getnonce,${config.clientId},${timestamp}`;
2018
+ const hashedSignature = await hmacSha256(signature, config.clientSecret);
2019
+ const nonceUrl = new URL("https://wbsapi.withings.net/v2/signature");
2020
+ nonceUrl.searchParams.set("action", "getnonce");
2021
+ nonceUrl.searchParams.set("client_id", config.clientId);
2022
+ nonceUrl.searchParams.set("timestamp", timestamp.toString());
2023
+ nonceUrl.searchParams.set("signature", hashedSignature);
2024
+ const nonceTarget = nonceUrl.toString();
2025
+ const nonceResponse = await fetch(nonceTarget, {
2026
+ ...h2IfHttps(nonceTarget),
2027
+ method: "POST"
2028
+ });
2029
+ const nonceData = await nonceResponse.json();
2030
+ if (nonceData.status === 0) {
2031
+ return {
2032
+ hashedSignature,
2033
+ nonce: nonceData.body.nonce
2034
+ };
2035
+ }
2036
+ return;
2037
+ };
2038
+ var h2IfHttps = (url) => {
2039
+ const init = url.startsWith("https://") ? { protocol: "http2" } : {};
2040
+ return init;
2041
+ };
2042
+ var hmacSha256 = async (message, secret) => {
2043
+ const encoder = new TextEncoder;
2044
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { hash: "SHA-256", name: "HMAC" }, false, ["sign"]);
2045
+ const sigBuffer = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
2046
+ return Array.from(new Uint8Array(sigBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
2047
+ };
2048
+ var extractPropFromIdentity = (identity, keys, propType) => {
2049
+ let value = identity;
2050
+ for (const key of keys) {
2051
+ if (Array.isArray(value))
2052
+ value = value[Number(key)];
2053
+ if (!isObject(value)) {
2054
+ throw new Error(`Invalid identity data shape: expected object, got ${typeof value}`);
2055
+ }
2056
+ value = value[key];
2057
+ }
2058
+ if (propType !== undefined && !isExpectedType(value, propType)) {
2059
+ throw new Error(`Invalid identity data shape: expected ${propType}, got ${typeof value}`);
2060
+ }
2061
+ return value;
2062
+ };
2063
+ var getProviderSubjectKeys = (providerConfiguration, source) => providerConfiguration.subjectBySource?.[source] ?? providerConfiguration.subject;
2064
+ var setPropInIdentity = (identity, keys, value) => {
2065
+ if (keys.length === 0) {
2066
+ return identity;
2067
+ }
2068
+ let cursor = identity;
2069
+ for (const key of keys.slice(0, -1)) {
2070
+ const next = cursor[key];
2071
+ cursor[key] = isObject(next) ? next : {};
2072
+ cursor = cursor[key];
2073
+ }
2074
+ cursor[keys[keys.length - 1]] = value;
2075
+ return identity;
2076
+ };
2077
+ var normalizeProviderIdentity = ({
2078
+ identity,
2079
+ providerConfiguration,
2080
+ source
2081
+ }) => {
2082
+ const sourceKeys = getProviderSubjectKeys(providerConfiguration, source);
2083
+ const canonicalKeys = providerConfiguration.subject;
2084
+ if (sourceKeys.join(".") === canonicalKeys.join(".")) {
2085
+ return identity;
2086
+ }
2087
+ const subject = extractPropFromIdentity(identity, sourceKeys, providerConfiguration.subjectType);
2088
+ const normalizedIdentity = structuredClone(identity);
2089
+ return setPropInIdentity(normalizedIdentity, canonicalKeys, subject);
2090
+ };
2091
+ var createS256CodeChallenge = async (codeVerifier) => {
2092
+ const data = new TextEncoder().encode(codeVerifier);
2093
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
2094
+ return base64Url(hashBuffer);
2095
+ };
2096
+ var createRandomBase64UrlGenerator = (length) => () => {
2097
+ const buffer = crypto.getRandomValues(new Uint8Array(length));
2098
+ return base64Url(buffer);
2099
+ };
2100
+ var generateCodeVerifier = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);
2101
+ var generateState = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);
2102
+ var base64Url = (input) => encodeBase64(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2103
+ var ALG_ES256 = "ES256";
2104
+ var ALG_RS256 = "RS256";
2105
+ var CLOCK_SKEW_SECONDS = 60;
2106
+ var DEFAULT_SCOPES = ["openid", "email", "profile"];
2107
+ var JWKS_REFETCH_COOLDOWN_MS = 60000;
2108
+ var JWT_SEGMENT_COUNT = 3;
2109
+ var MILLISECONDS_PER_SECOND = 1000;
2110
+ var trimTrailingSlash = (value) => value.endsWith("/") ? value.slice(0, -1) : value;
2111
+ var fetchJson = async (url) => {
2112
+ const response = await fetch(url, {
2113
+ headers: { accept: "application/json" }
2114
+ });
2115
+ if (!response.ok) {
2116
+ throw new Error(`Request to ${url} failed with status ${response.status}`);
2117
+ }
2118
+ return response.json();
2119
+ };
2120
+ var decodeJsonSegment = (segment) => {
2121
+ const decoded = decodeBase64(segment);
2122
+ if (typeof decoded !== "string") {
2123
+ throw new Error("Expected a base64url-encoded JWT segment");
2124
+ }
2125
+ const parsed = JSON.parse(decoded);
2126
+ if (typeof parsed !== "object" || parsed === null) {
2127
+ throw new Error("Expected a JWT segment to decode to a JSON object");
2128
+ }
2129
+ return parsed;
2130
+ };
2131
+ var importVerificationKey = (jwk, alg) => {
2132
+ if (alg === ALG_RS256) {
2133
+ return crypto.subtle.importKey("jwk", jwk, { hash: "SHA-256", name: "RSASSA-PKCS1-v1_5" }, false, ["verify"]);
2134
+ }
2135
+ if (alg === ALG_ES256) {
2136
+ return crypto.subtle.importKey("jwk", jwk, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
2137
+ }
2138
+ throw new Error(`Unsupported id_token signing algorithm "${alg}"`);
2139
+ };
2140
+ var verifySignature = (key, alg, signingInput, signature) => {
2141
+ const algorithm = alg === ALG_ES256 ? { hash: "SHA-256", name: "ECDSA" } : { name: "RSASSA-PKCS1-v1_5" };
2142
+ return crypto.subtle.verify(algorithm, key, new Uint8Array(signature), new TextEncoder().encode(signingInput));
2143
+ };
2144
+ var selectKey = (jwks, kid) => jwks.find((jwk) => kid === undefined || jwk.kid === kid);
2145
+ var assertClaims = (payload, expected) => {
2146
+ const aud = Reflect.get(payload, "aud");
2147
+ const exp = Reflect.get(payload, "exp");
2148
+ const iss = Reflect.get(payload, "iss");
2149
+ const sub = Reflect.get(payload, "sub");
2150
+ const audiences = Array.isArray(aud) ? aud : [aud];
2151
+ const nowSeconds = Math.floor(Date.now() / MILLISECONDS_PER_SECOND);
2152
+ if (iss !== expected.issuer) {
2153
+ throw new Error('id_token "iss" does not match the provider issuer');
2154
+ }
2155
+ if (typeof sub !== "string" || sub.length === 0) {
2156
+ throw new Error('id_token is missing "sub"');
2157
+ }
2158
+ if (!audiences.includes(expected.audience)) {
2159
+ throw new Error('id_token "aud" does not include the client id');
2160
+ }
2161
+ if (typeof exp !== "number" || exp + CLOCK_SKEW_SECONDS < nowSeconds) {
2162
+ throw new Error("id_token has expired");
2163
+ }
2164
+ if (expected.nonce !== undefined && Reflect.get(payload, "nonce") !== expected.nonce) {
2165
+ throw new Error('id_token "nonce" does not match');
2166
+ }
2167
+ const claims = { ...payload, aud, exp, iss, sub };
2168
+ return claims;
2169
+ };
2170
+ var verifyIdToken = async ({
2171
+ audience,
2172
+ idToken,
2173
+ issuer,
2174
+ jwks,
2175
+ nonce
2176
+ }) => {
2177
+ const segments = idToken.split(".");
2178
+ const [headerSegment, payloadSegment, signatureSegment] = segments;
2179
+ if (segments.length !== JWT_SEGMENT_COUNT || headerSegment === undefined || payloadSegment === undefined || signatureSegment === undefined) {
2180
+ throw new Error("Invalid id_token: expected three segments");
2181
+ }
2182
+ const header = decodeJsonSegment(headerSegment);
2183
+ const alg = Reflect.get(header, "alg");
2184
+ const kid = Reflect.get(header, "kid");
2185
+ if (typeof alg !== "string") {
2186
+ throw new Error('id_token header is missing "alg"');
2187
+ }
2188
+ const jwk = selectKey(jwks, typeof kid === "string" ? kid : undefined);
2189
+ if (jwk === undefined) {
2190
+ throw new Error('No JWKS key matches the id_token "kid"');
2191
+ }
2192
+ const key = await importVerificationKey(jwk, alg);
2193
+ const signature = decodeBase64(signatureSegment, true);
2194
+ if (typeof signature === "string") {
2195
+ throw new Error("Failed to decode the id_token signature");
2196
+ }
2197
+ const isValid = await verifySignature(key, alg, `${headerSegment}.${payloadSegment}`, signature);
2198
+ if (!isValid) {
2199
+ throw new Error("id_token signature verification failed");
2200
+ }
2201
+ return assertClaims(decodeJsonSegment(payloadSegment), {
2202
+ audience,
2203
+ issuer,
2204
+ nonce
2205
+ });
2206
+ };
2207
+ var toDiscoveryDocument = (value, expectedIssuer) => {
2208
+ if (typeof value !== "object" || value === null) {
2209
+ throw new Error("OIDC discovery document is not a JSON object");
2210
+ }
2211
+ const issuer = Reflect.get(value, "issuer");
2212
+ const authorizationEndpoint = Reflect.get(value, "authorization_endpoint");
2213
+ const tokenEndpoint = Reflect.get(value, "token_endpoint");
2214
+ const jwksUri = Reflect.get(value, "jwks_uri");
2215
+ const userinfoEndpoint = Reflect.get(value, "userinfo_endpoint");
2216
+ if (typeof issuer !== "string" || typeof authorizationEndpoint !== "string" || typeof tokenEndpoint !== "string" || typeof jwksUri !== "string") {
2217
+ throw new Error("OIDC discovery document is missing required endpoints");
2218
+ }
2219
+ if (trimTrailingSlash(issuer) !== trimTrailingSlash(expectedIssuer)) {
2220
+ throw new Error(`OIDC discovery issuer "${issuer}" does not match configured issuer "${expectedIssuer}"`);
2221
+ }
2222
+ return {
2223
+ authorization_endpoint: authorizationEndpoint,
2224
+ issuer,
2225
+ jwks_uri: jwksUri,
2226
+ token_endpoint: tokenEndpoint,
2227
+ userinfo_endpoint: typeof userinfoEndpoint === "string" ? userinfoEndpoint : undefined
2228
+ };
2229
+ };
2230
+ var fetchDiscoveryDocument = async (issuer) => {
2231
+ const base = trimTrailingSlash(issuer);
2232
+ const document = await fetchJson(`${base}/.well-known/openid-configuration`);
2233
+ return toDiscoveryDocument(document, issuer);
2234
+ };
2235
+ var fetchJwks = async (jwksUri) => {
2236
+ const body = await fetchJson(jwksUri);
2237
+ const value = Reflect.get(body ?? {}, "keys");
2238
+ if (!Array.isArray(value)) {
2239
+ throw new Error('JWKS response is missing a "keys" array');
2240
+ }
2241
+ const keys = value;
2242
+ return keys;
2243
+ };
2244
+ var createOIDCClient = async (config) => {
2245
+ const discovery = await fetchDiscoveryDocument(config.issuer);
2246
+ const scopes = config.scopes !== undefined && config.scopes.length > 0 ? config.scopes : DEFAULT_SCOPES;
2247
+ let cachedJwks;
2248
+ let jwksFetchedAtMs = 0;
2249
+ const resolveJwks = async (forceRefresh) => {
2250
+ const isStale = Date.now() - jwksFetchedAtMs > JWKS_REFETCH_COOLDOWN_MS;
2251
+ if (cachedJwks === undefined || forceRefresh && isStale) {
2252
+ cachedJwks = await fetchJwks(discovery.jwks_uri);
2253
+ jwksFetchedAtMs = Date.now();
2254
+ }
2255
+ return cachedJwks;
2256
+ };
2257
+ const createAuthorizationUrl = async (options) => {
2258
+ const url = new URL(discovery.authorization_endpoint);
2259
+ const challenge = await createS256CodeChallenge(options.codeVerifier);
2260
+ const { searchParams } = url;
2261
+ searchParams.set("client_id", config.clientId);
2262
+ searchParams.set("code_challenge", challenge);
2263
+ searchParams.set("code_challenge_method", "S256");
2264
+ searchParams.set("redirect_uri", config.redirectUri);
2265
+ searchParams.set("response_type", "code");
2266
+ searchParams.set("scope", (options.scope ?? scopes).join(" "));
2267
+ searchParams.set("state", options.state);
2268
+ if (options.nonce !== undefined) {
2269
+ searchParams.set("nonce", options.nonce);
2270
+ }
2271
+ return url;
2272
+ };
2273
+ const validateAuthorizationCode = async (options) => {
2274
+ const body = new URLSearchParams;
2275
+ body.set("client_id", config.clientId);
2276
+ body.set("client_secret", config.clientSecret);
2277
+ body.set("code", options.code);
2278
+ body.set("code_verifier", options.codeVerifier);
2279
+ body.set("grant_type", "authorization_code");
2280
+ body.set("redirect_uri", config.redirectUri);
2281
+ const response = await fetch(discovery.token_endpoint, {
2282
+ body,
2283
+ headers: {
2284
+ accept: "application/json",
2285
+ "content-type": "application/x-www-form-urlencoded"
2286
+ },
2287
+ method: "POST"
2288
+ });
2289
+ if (!response.ok) {
2290
+ throw new Error(`OIDC token request failed with status ${response.status}`);
2291
+ }
2292
+ const tokens = await response.json();
2293
+ return tokens;
2294
+ };
2295
+ const verifyToken = async (idToken, options) => {
2296
+ const jwks = await resolveJwks(false);
2297
+ const params = {
2298
+ audience: config.clientId,
2299
+ idToken,
2300
+ issuer: discovery.issuer,
2301
+ nonce: options?.nonce
2302
+ };
2303
+ try {
2304
+ return await verifyIdToken({ ...params, jwks });
2305
+ } catch (error) {
2306
+ const refreshed = await resolveJwks(true);
2307
+ if (refreshed === jwks)
2308
+ throw error;
2309
+ return verifyIdToken({ ...params, jwks: refreshed });
2310
+ }
2311
+ };
2312
+ const fetchUserProfile = async (accessToken) => {
2313
+ if (discovery.userinfo_endpoint === undefined) {
2314
+ throw new Error("OIDC provider does not expose a userinfo endpoint");
2315
+ }
2316
+ const response = await fetch(discovery.userinfo_endpoint, {
2317
+ headers: {
2318
+ accept: "application/json",
2319
+ authorization: `Bearer ${accessToken}`
2320
+ }
2321
+ });
2322
+ if (!response.ok) {
2323
+ throw new Error(`OIDC userinfo request failed with status ${response.status}`);
2324
+ }
2325
+ const profile = await response.json();
2326
+ return profile;
2327
+ };
2328
+ return {
2329
+ createAuthorizationUrl,
2330
+ discovery,
2331
+ fetchUserProfile,
2332
+ validateAuthorizationCode,
2333
+ verifyIdToken: verifyToken
2334
+ };
2335
+ };
2336
+ var oidcProviderOptions = Object.keys(providers).filter(isOIDCProviderOption);
2337
+ var pkceProviderOptions = Object.keys(providers).filter(isPKCEProviderOption);
2338
+ var providerOptions = Object.keys(providers).filter(isValidProviderOption);
2339
+ var refreshableProviderOptions = Object.keys(providers).filter(isRefreshableProviderOption);
2340
+ var revocableProviderOptions = Object.keys(providers).filter(isRevocableProviderOption);
2341
+ var scopeRequiredProviderOptions = Object.keys(providers).filter(isScopeRequiredProviderOption);
2342
+ var createOAuth2Client = async (providerName, config) => {
2343
+ const meta = providers[providerName];
2344
+ const isConfigPropertyFunction = (cfgProp) => typeof cfgProp === "function";
2345
+ const resolveConfigProp = async (cfgProp) => {
2346
+ const result = isConfigPropertyFunction(cfgProp) ? cfgProp(config) : cfgProp;
2347
+ return result;
2348
+ };
2349
+ const authorizationUrl = await resolveConfigProp(meta.authorizationUrl);
2350
+ const tokenUrl = await resolveConfigProp(meta.tokenRequest.url);
2351
+ return {
2352
+ async createAuthorizationUrl(opts) {
2353
+ const { state, scope = [], searchParams = [], codeVerifier } = opts;
2354
+ const url = new URL(authorizationUrl);
2355
+ url.searchParams.set("response_type", "code");
2356
+ url.searchParams.set("client_id", config.clientId);
2357
+ if (config.redirectUri)
2358
+ url.searchParams.set("redirect_uri", config.redirectUri);
2359
+ if (state)
2360
+ url.searchParams.set("state", state);
2361
+ if (scope.length !== 0) {
2362
+ const delimeter = providerName === "withings" ? "," : " ";
2363
+ url.searchParams.set("scope", scope.join(delimeter));
2364
+ }
2365
+ if (meta.PKCEMethod !== undefined) {
2366
+ if (!codeVerifier) {
2367
+ throw new Error("`codeVerifier` is required when PKCE is enabled");
2368
+ }
2369
+ const codeChallenge = meta.PKCEMethod === "S256" ? await createS256CodeChallenge(codeVerifier) : codeVerifier;
2370
+ url.searchParams.set("code_challenge_method", meta.PKCEMethod);
2371
+ url.searchParams.set("code_challenge", codeChallenge);
2372
+ }
2373
+ Object.entries(resolveConfigProp(meta.createAuthorizationURLSearchParams) ?? {}).forEach(([key, value]) => url.searchParams.set(key, value));
2374
+ searchParams.forEach(([key, value]) => url.searchParams.set(key, value));
2375
+ return url;
2376
+ },
2377
+ async fetchUserProfile(accessToken) {
2378
+ const { profileRequest } = meta;
2379
+ const {
2380
+ url,
2381
+ method,
2382
+ authIn,
2383
+ searchParams,
2384
+ body: profileBody,
2385
+ headers,
2386
+ encoding
2387
+ } = profileRequest;
2388
+ const endpoint = new URL(await resolveConfigProp(url));
2389
+ const resolvedBody = await resolveConfigProp(profileBody);
2390
+ new URLSearchParams(await resolveConfigProp(searchParams)).forEach((value, key) => endpoint.searchParams.append(key, value));
2391
+ let headerEntries = [];
2392
+ const rawHeaders = headers ? await resolveConfigProp(headers) : undefined;
2393
+ if (rawHeaders instanceof Headers)
2394
+ headerEntries = Array.from(rawHeaders.entries());
2395
+ else if (Array.isArray(rawHeaders))
2396
+ headerEntries = rawHeaders;
2397
+ else if (rawHeaders && typeof rawHeaders === "object")
2398
+ headerEntries = Object.entries(rawHeaders);
2399
+ const profileHeaders = Object.fromEntries(headerEntries.filter(([, value]) => value !== ""));
2400
+ if (authIn === "header") {
2401
+ profileHeaders.Authorization = `Bearer ${accessToken}`;
2402
+ } else {
2403
+ endpoint.searchParams.append("access_token", accessToken);
2404
+ }
2405
+ const init = { headers: profileHeaders, method };
2406
+ if (method === "POST" && resolvedBody !== undefined) {
2407
+ profileHeaders["Content-Type"] = encoding;
2408
+ init.body = encoding === "application/json" ? JSON.stringify(resolvedBody) : new URLSearchParams(resolvedBody).toString();
2409
+ }
2410
+ const profileTarget = endpoint.toString();
2411
+ const response = await fetch(profileTarget, {
2412
+ ...h2IfHttps(profileTarget),
2413
+ ...init
2414
+ });
2415
+ if (!response.ok)
2416
+ throw await createOAuth2FetchError(response);
2417
+ return response.json();
2418
+ },
2419
+ async refreshAccessToken(refreshToken) {
2420
+ const { authIn, encoding } = meta.tokenRequest;
2421
+ const params = new URLSearchParams(meta.refreshAccessTokenBody);
2422
+ params.set("grant_type", "refresh_token");
2423
+ params.set("refresh_token", refreshToken);
2424
+ const { clientId } = config;
2425
+ let clientSecretValue;
2426
+ if (hasClientSecret(config)) {
2427
+ clientSecretValue = config.clientSecret;
2428
+ params.set("client_id", clientId);
2429
+ params.set("client_secret", clientSecretValue);
2430
+ }
2431
+ const request = createOAuth2Request({
2432
+ authIn,
2433
+ body: params,
2434
+ clientId,
2435
+ clientSecret: clientSecretValue,
2436
+ encoding,
2437
+ url: tokenUrl
2438
+ });
2439
+ const response = await fetch(request, {
2440
+ ...h2IfHttps(request.url)
2441
+ });
2442
+ if (!response.ok)
2443
+ throw await createOAuth2FetchError(response);
2444
+ return response.json();
2445
+ },
2446
+ async revokeToken(token) {
2447
+ const { revocationRequest } = meta;
2448
+ if (!revocationRequest) {
2449
+ throw new Error("Token revocation not defined for this provider");
2450
+ }
2451
+ const { url, authIn, body, headers, tokenParamName } = revocationRequest;
2452
+ const endpoint = await resolveConfigProp(url);
2453
+ const resolvedBody = await resolveConfigProp(body);
2454
+ const revocationBody = new URLSearchParams(resolvedBody);
2455
+ const revocationHeaders = new Headers(headers && await resolveConfigProp(headers));
2456
+ const { clientId } = config;
2457
+ const clientSecret = hasClientSecret(config) ? config.clientSecret : undefined;
2458
+ let request;
2459
+ if (authIn === "body") {
2460
+ revocationBody.set(tokenParamName, token);
2461
+ revocationBody.set("client_id", clientId);
2462
+ if (clientSecret)
2463
+ revocationBody.set("client_secret", clientSecret);
2464
+ request = createOAuth2Request({
2465
+ authIn: "body",
2466
+ body: revocationBody,
2467
+ clientId,
2468
+ clientSecret,
2469
+ encoding: "application/x-www-form-urlencoded",
2470
+ headers: revocationHeaders,
2471
+ url: endpoint.toString()
2472
+ });
2473
+ } else if (authIn === "header") {
2474
+ revocationHeaders.set("Authorization", `Bearer ${token}`);
2475
+ request = createOAuth2Request({
2476
+ authIn: "header",
2477
+ body: revocationBody,
2478
+ clientId,
2479
+ clientSecret,
2480
+ encoding: "application/x-www-form-urlencoded",
2481
+ headers: revocationHeaders,
2482
+ url: endpoint.toString()
2483
+ });
2484
+ } else {
2485
+ request = createOAuth2Request({
2486
+ authIn: "query",
2487
+ body: revocationBody,
2488
+ clientId,
2489
+ clientSecret,
2490
+ encoding: "application/x-www-form-urlencoded",
2491
+ headers: revocationHeaders,
2492
+ url: `${endpoint.toString()}?${tokenParamName}=${token}`
2493
+ });
2494
+ }
2495
+ const response = await fetch(request, {
2496
+ ...h2IfHttps(request.url)
2497
+ });
2498
+ if (!response.ok)
2499
+ throw await createOAuth2FetchError(response);
2500
+ },
2501
+ async validateAuthorizationCode(opts) {
2502
+ const { code, codeVerifier } = opts;
2503
+ const { authIn, encoding } = meta.tokenRequest;
2504
+ const bodyObj = {};
2505
+ for (const key in meta.validateAuthorizationCodeBody ?? {}) {
2506
+ const value = meta.validateAuthorizationCodeBody[key];
2507
+ if (typeof value === "string")
2508
+ bodyObj[key] = value;
2509
+ }
2510
+ bodyObj.grant_type = "authorization_code";
2511
+ bodyObj.code = code;
2512
+ if (config.redirectUri)
2513
+ bodyObj.redirect_uri = config.redirectUri;
2514
+ if (meta.PKCEMethod !== undefined) {
2515
+ if (!codeVerifier) {
2516
+ throw new Error("codeVerifier required when PKCE is enabled");
2517
+ }
2518
+ bodyObj.code_verifier = codeVerifier;
2519
+ }
2520
+ const payload = encoding === "application/json" ? bodyObj : new URLSearchParams(bodyObj);
2521
+ const request = createOAuth2Request({
2522
+ authIn,
2523
+ body: payload,
2524
+ clientId: config.clientId,
2525
+ clientSecret: hasClientSecret(config) ? config.clientSecret : undefined,
2526
+ encoding,
2527
+ url: tokenUrl
2528
+ });
2529
+ const response = await fetch(request, {
2530
+ ...h2IfHttps(request.url)
2531
+ });
2532
+ if (!response.ok)
2533
+ throw await createOAuth2FetchError(response);
2534
+ return response.json();
2535
+ }
2536
+ };
2537
+ };
2538
+ export {
2539
+ scopeRequiredProviderOptions,
2540
+ revocableProviderOptions,
2541
+ refreshableProviderOptions,
2542
+ providers,
2543
+ providerOptions,
2544
+ pkceProviderOptions,
2545
+ oidcProviderOptions,
2546
+ isValidProviderOption,
2547
+ isRevocableProviderOption,
2548
+ isRevocableOAuth2Client,
2549
+ isRefreshableProviderOption,
2550
+ isRefreshableOAuth2Client,
2551
+ isPKCEProviderOption,
2552
+ isOIDCProviderOption,
2553
+ extractPropFromIdentity,
2554
+ decodeJWT
2555
+ };
2556
+
2557
+ //# debugId=2E1CE4D0162FAFF764756E2164756E21
2558
+ //# sourceMappingURL=index.js.map