Skip to content

Commit fa72922

Browse files
authored
Merge pull request #10 from fief-dev/nextjs/ssr
nextjs: implement SSR functions to retrieve user and access token info
2 parents 94d515b + 2977b29 commit fa72922

20 files changed

+2381
-1939
lines changed

.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"node": true,
66
"jest/globals": true
77
},
8+
"globals": {
9+
"RequestInit": true
10+
},
811
"ignorePatterns": [
912
"build/"
1013
],

.vscode/settings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
}
66
],
77
"editor.codeActionsOnSave": {
8-
"source.fixAll.eslint": true
8+
"source.fixAll.eslint": "explicit"
99
},
1010
"eslint.validate": [
1111
"javascript"

nextjs/react/package.json

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"name": "@fief/fief/nextjs/react",
33
"private": true,
4-
"main": "../../build/cjs/nextjs/react.js",
5-
"module": "../../build/esm/nextjs/react.js",
6-
"types": "../../build/esm/nextjs/react.d.ts"
4+
"main": "../../build/cjs/nextjs/react/index.js",
5+
"module": "../../build/esm/nextjs/react/index.js",
6+
"types": "../../build/esm/nextjs/react/index.d.ts",
7+
"peerDependencies": {
8+
"react": "^18.0.0",
9+
"react-dom": "^18.0.0"
10+
}
711
}

package-lock.json

+1,924-1,683
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"jest": "^29.0.3",
6262
"jest-environment-jsdom": "^29.0.3",
6363
"jest-location-mock": "^2.0.0",
64-
"next": "^13.2.4",
64+
"next": "^14.2.3",
6565
"node-fetch": "^2.7.0",
6666
"node-mocks-http": "^1.11.0",
6767
"ramda": "^0.29.0",
@@ -74,7 +74,7 @@
7474
},
7575
"dependencies": {
7676
"encoding": "^0.1.13",
77-
"jose": "^4.6.0",
77+
"jose": "^5.4.0",
7878
"path-to-regexp": "^6.2.1"
7979
},
8080
"jest": {}

rollup.config.mjs

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@ const external = [
88
'crypto',
99
'jose',
1010
'next',
11+
'next/cache',
12+
'next/headers',
1113
'next/server',
1214
'path-to-regexp',
1315
'react',
1416
'react/jsx-runtime',
1517
];
18+
const globals = {
19+
crypto: 'crypto',
20+
};
1621

1722
export default [
1823
// browser-friendly UMD build
@@ -23,6 +28,7 @@ export default [
2328
file: 'build/index.umd.js',
2429
format: 'umd',
2530
sourcemap: true,
31+
globals,
2632
},
2733
plugins: [
2834
nodeResolve({
@@ -43,7 +49,7 @@ export default [
4349
'src/react/index.ts',
4450
'src/express/index.ts',
4551
'src/nextjs/index.ts',
46-
'src/nextjs/react.tsx',
52+
'src/nextjs/react/index.ts',
4753
],
4854
plugins: [
4955
typescript({
@@ -59,6 +65,7 @@ export default [
5965
sourcemap: true,
6066
preserveModules: true,
6167
preserveModulesRoot: 'src',
68+
globals,
6269
},
6370
],
6471
external,
@@ -70,7 +77,7 @@ export default [
7077
'src/react/index.ts',
7178
'src/express/index.ts',
7279
'src/nextjs/index.ts',
73-
'src/nextjs/react.tsx',
80+
'src/nextjs/react/index.ts',
7481
],
7582
plugins: [
7683
typescript({
@@ -87,6 +94,7 @@ export default [
8794
sourcemap: true,
8895
preserveModules: true,
8996
preserveModulesRoot: 'src',
97+
globals,
9098
},
9199
],
92100
external,

src/client.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,16 @@ export interface FiefParameters {
228228
* @see [ID Token encryption](https://docs.fief.dev/going-further/id-token-encryption/)
229229
*/
230230
encryptionKey?: string;
231+
232+
/**
233+
* Additional fetch init options for `getOpenIDConfiguration` and `getJWKS` requests.
234+
*
235+
* Mostly useful to control fetch cache.
236+
*
237+
* @see [fetch cache property](https://developer.mozilla.org/en-US/docs/Web/API/Request/cache)
238+
* @see [Next.js fetch](https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options)
239+
*/
240+
requestInit?: RequestInit;
231241
}
232242

233243
/**
@@ -253,6 +263,8 @@ export class Fief {
253263

254264
private fetch: typeof fetch;
255265

266+
private requestInit?: RequestInit;
267+
256268
private openIDConfiguration?: Record<string, any>;
257269

258270
private jwks?: jose.JSONWebKeySet;
@@ -274,6 +286,7 @@ export class Fief {
274286
}
275287

276288
this.fetch = getFetch();
289+
this.requestInit = parameters.requestInit;
277290

278291
this.crypto = getCrypto();
279292
}
@@ -348,6 +361,7 @@ export class Fief {
348361
* @param redirectURI - The exact same `redirectURI` you passed to the authorization URL.
349362
* @param codeVerifier - The raw [PKCE](https://docs.fief.dev/going-further/pkce/) code
350363
* used to generate the code challenge during authorization.
364+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
351365
*
352366
* @returns A token response and user information.
353367
*
@@ -360,6 +374,7 @@ export class Fief {
360374
code: string,
361375
redirectURI: string,
362376
codeVerifier?: string,
377+
requestInit?: RequestInit,
363378
): Promise<[FiefTokenResponse, FiefUserInfo]> {
364379
const openIDConfiguration = await this.getOpenIDConfiguration();
365380
const payload = serializeQueryString({
@@ -374,9 +389,11 @@ export class Fief {
374389
const response = await this.fetch(
375390
openIDConfiguration.token_endpoint,
376391
{
392+
...requestInit || {},
377393
method: 'POST',
378394
body: payload,
379395
headers: {
396+
...requestInit && requestInit.headers ? requestInit.headers : {},
380397
'Content-Type': 'application/x-www-form-urlencoded',
381398
},
382399
},
@@ -402,6 +419,7 @@ export class Fief {
402419
* If not provided, the access token will share the same list of scopes
403420
* as requested the first time.
404421
* Otherwise, it should be a subset of the original list of scopes.
422+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
405423
*
406424
* @returns A token response and user information.
407425
*
@@ -413,6 +431,7 @@ export class Fief {
413431
public async authRefreshToken(
414432
refreshToken: string,
415433
scope?: string[],
434+
requestInit?: RequestInit,
416435
): Promise<[FiefTokenResponse, FiefUserInfo]> {
417436
const openIDConfiguration = await this.getOpenIDConfiguration();
418437
const payload = serializeQueryString({
@@ -425,9 +444,11 @@ export class Fief {
425444
const response = await this.fetch(
426445
openIDConfiguration.token_endpoint,
427446
{
447+
...requestInit || {},
428448
method: 'POST',
429449
body: payload,
430450
headers: {
451+
...requestInit && requestInit.headers ? requestInit.headers : {},
431452
'Content-Type': 'application/x-www-form-urlencoded',
432453
},
433454
},
@@ -452,6 +473,7 @@ export class Fief {
452473
* @param requiredScopes - Optional list of scopes to check for.
453474
* @param requiredACR - Optional minimum ACR level required. Read more: https://docs.fief.dev/going-further/acr/
454475
* @param requiredPermissions - Optional list of permissions to check for.
476+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
455477
*
456478
* @returns {@link FiefAccessTokenInfo}
457479
* @throws {@link FiefAccessTokenInvalid} if the access token is invalid.
@@ -548,6 +570,7 @@ export class Fief {
548570
* Return fresh {@link FiefUserInfo} from the Fief API using a valid access token.
549571
*
550572
* @param accessToken - A valid access token.
573+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
551574
*
552575
* @returns Fresh user information.
553576
*
@@ -556,13 +579,15 @@ export class Fief {
556579
* userinfo = await fief.userinfo('ACCESS_TOKEN');
557580
* ```
558581
*/
559-
public async userinfo(accessToken: string): Promise<FiefUserInfo> {
582+
public async userinfo(accessToken: string, requestInit?: RequestInit): Promise<FiefUserInfo> {
560583
const openIDConfiguration = await this.getOpenIDConfiguration();
561584
const response = await this.fetch(
562585
openIDConfiguration.userinfo_endpoint,
563586
{
587+
...requestInit || {},
564588
method: 'GET',
565589
headers: {
590+
...requestInit && requestInit.headers ? requestInit.headers : {},
566591
Authorization: `Bearer ${accessToken}`,
567592
},
568593
},
@@ -577,6 +602,7 @@ export class Fief {
577602
*
578603
* @param accessToken - A valid access token.
579604
* @param data - An object containing the data to update.
605+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
580606
*
581607
* @returns Updated user information.
582608
*
@@ -590,14 +616,17 @@ export class Fief {
590616
public async updateProfile(
591617
accessToken: string,
592618
data: Record<string, any>,
619+
requestInit?: RequestInit,
593620
): Promise<FiefUserInfo> {
594621
const updateProfileEndpoint = `${this.baseURL}/api/profile`;
595622
const response = await this.fetch(
596623
updateProfileEndpoint,
597624
{
625+
...requestInit || {},
598626
method: 'PATCH',
599627
body: JSON.stringify(data),
600628
headers: {
629+
...requestInit && requestInit.headers ? requestInit.headers : {},
601630
'Content-Type': 'application/json',
602631
Authorization: `Bearer ${accessToken}`,
603632
},
@@ -615,6 +644,7 @@ export class Fief {
615644
*
616645
* @param accessToken - A valid access token.
617646
* @param newPassword - The new password.
647+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
618648
*
619649
* @returns Updated user information.
620650
*
@@ -626,14 +656,17 @@ export class Fief {
626656
public async changePassword(
627657
accessToken: string,
628658
newPassword: string,
659+
requestInit?: RequestInit,
629660
): Promise<FiefUserInfo> {
630661
const updateProfileEndpoint = `${this.baseURL}/api/password`;
631662
const response = await this.fetch(
632663
updateProfileEndpoint,
633664
{
665+
...requestInit || {},
634666
method: 'PATCH',
635667
body: JSON.stringify({ password: newPassword }),
636668
headers: {
669+
...requestInit && requestInit.headers ? requestInit.headers : {},
637670
'Content-Type': 'application/json',
638671
Authorization: `Bearer ${accessToken}`,
639672
},
@@ -654,6 +687,7 @@ export class Fief {
654687
*
655688
* @param accessToken - A valid access token.
656689
* @param newPassword - The new email address.
690+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
657691
*
658692
* @returns Updated user information.
659693
*
@@ -665,14 +699,17 @@ export class Fief {
665699
public async emailChange(
666700
accessToken: string,
667701
email: string,
702+
requestInit?: RequestInit,
668703
): Promise<FiefUserInfo> {
669704
const updateProfileEndpoint = `${this.baseURL}/api/email/change`;
670705
const response = await this.fetch(
671706
updateProfileEndpoint,
672707
{
708+
...requestInit || {},
673709
method: 'PATCH',
674710
body: JSON.stringify({ email }),
675711
headers: {
712+
...requestInit && requestInit.headers ? requestInit.headers : {},
676713
'Content-Type': 'application/json',
677714
Authorization: `Bearer ${accessToken}`,
678715
},
@@ -691,6 +728,7 @@ export class Fief {
691728
*
692729
* @param accessToken - A valid access token.
693730
* @param newPassword - The new email address.
731+
* @param requestInit - Additional fetch init options. Mostly useful to control fetch cache.
694732
*
695733
* @returns Updated user information.
696734
*
@@ -702,14 +740,17 @@ export class Fief {
702740
public async emailVerify(
703741
accessToken: string,
704742
code: string,
743+
requestInit?: RequestInit,
705744
): Promise<FiefUserInfo> {
706745
const updateProfileEndpoint = `${this.baseURL}/api/email/verify`;
707746
const response = await this.fetch(
708747
updateProfileEndpoint,
709748
{
749+
...requestInit || {},
710750
method: 'POST',
711751
body: JSON.stringify({ code }),
712752
headers: {
753+
...requestInit && requestInit.headers ? requestInit.headers : {},
713754
'Content-Type': 'application/json',
714755
Authorization: `Bearer ${accessToken}`,
715756
},
@@ -752,6 +793,7 @@ export class Fief {
752793
const response = await this.fetch(
753794
`${this.baseURL}/.well-known/openid-configuration`,
754795
{
796+
...this.requestInit || {},
755797
method: 'GET',
756798
},
757799
);
@@ -771,6 +813,7 @@ export class Fief {
771813
const response = await this.fetch(
772814
openIDConfiguration.jwks_uri,
773815
{
816+
...this.requestInit || {},
774817
method: 'GET',
775818
},
776819
);

src/crypto/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ export const getCrypto = (): ICryptoHelper => {
2828
throw new CryptoHelperError('Cannot find a crypto implementation for your environment');
2929
};
3030

31-
export { CryptoHelperError, ICryptoHelper };
31+
export { CryptoHelperError };
32+
export type { ICryptoHelper };

src/express/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,12 @@ const createMiddleware = (parameters: FiefAuthParameters) => {
193193
};
194194

195195
export {
196-
AuthenticateRequestParameters,
197196
authorizationSchemeGetter,
198197
cookieGetter,
199198
createMiddleware,
199+
};
200+
export type {
201+
AuthenticateRequestParameters,
200202
IUserInfoCache,
201203
TokenGetter,
202204
};

0 commit comments

Comments
 (0)