@@ -3,7 +3,7 @@ import type {
3
3
CheckAuthorizationParamsWithCustomPermissions ,
4
4
CheckAuthorizationWithCustomPermissions ,
5
5
} from '@clerk/types' ;
6
- import { notFound } from 'next/navigation' ;
6
+ import { notFound , redirect } from 'next/navigation' ;
7
7
8
8
import { authAuthHeaderMissing } from '../../server/errors' ;
9
9
import { buildClerkProps , createGetAuth } from '../../server/getAuth' ;
@@ -17,14 +17,23 @@ type AuthSignedIn = AuthObjectWithDeprecatedResources<
17
17
* This function is experimental as it throws a Nextjs notFound error if user is not authenticated or authorized.
18
18
* In the future we would investigate a way to throw a more appropriate error that clearly describes the not authorized of authenticated status.
19
19
*/
20
- protect : (
21
- params ?:
22
- | CheckAuthorizationParamsWithCustomPermissions
23
- | ( ( has : CheckAuthorizationWithCustomPermissions ) => boolean ) ,
24
- ) => AuthObjectWithDeprecatedResources < SignedInAuthObject > ;
20
+ protect : {
21
+ (
22
+ params ?:
23
+ | CheckAuthorizationParamsWithCustomPermissions
24
+ | ( ( has : CheckAuthorizationWithCustomPermissions ) => boolean ) ,
25
+ options ?: { redirectUrl : string } ,
26
+ ) : AuthObjectWithDeprecatedResources < SignedInAuthObject > ;
27
+
28
+ ( params ?: { redirectUrl : string } ) : AuthObjectWithDeprecatedResources < SignedInAuthObject > ;
29
+ } ;
25
30
}
26
31
> ;
27
32
33
+ type ProtectGeneric = {
34
+ protect : ( params ?: unknown , options ?: unknown ) => AuthObjectWithDeprecatedResources < SignedInAuthObject > ;
35
+ } ;
36
+
28
37
type AuthSignedOut = AuthObjectWithDeprecatedResources <
29
38
SignedOutAuthObject & {
30
39
/**
@@ -42,39 +51,53 @@ export const auth = () => {
42
51
noAuthStatusMessage : authAuthHeaderMissing ( ) ,
43
52
} ) ( buildRequestLike ( ) ) ;
44
53
45
- ( authObject as AuthSignedIn ) . protect = params => {
54
+ ( authObject as unknown as ProtectGeneric ) . protect = ( params : any , options : any ) => {
55
+ const paramsOrFunction = params ?. redirectUrl
56
+ ? undefined
57
+ : ( params as
58
+ | CheckAuthorizationParamsWithCustomPermissions
59
+ | ( ( has : CheckAuthorizationWithCustomPermissions ) => boolean ) ) ;
60
+ const redirectUrl = ( params ?. redirectUrl || options ?. redirectUrl ) as string | undefined ;
61
+
62
+ const handleUnauthorized = ( ) : never => {
63
+ if ( redirectUrl ) {
64
+ redirect ( redirectUrl ) ;
65
+ }
66
+ notFound ( ) ;
67
+ } ;
68
+
46
69
/**
47
70
* User is not authenticated
48
71
*/
49
72
if ( ! authObject . userId ) {
50
- notFound ( ) ;
73
+ return handleUnauthorized ( ) ;
51
74
}
52
75
53
76
/**
54
77
* User is authenticated
55
78
*/
56
- if ( ! params ) {
79
+ if ( ! paramsOrFunction ) {
57
80
return { ...authObject } ;
58
81
}
59
82
60
83
/**
61
84
* if a function is passed and returns false then throw not found
62
85
*/
63
- if ( typeof params === 'function' ) {
64
- if ( params ( authObject . has ) ) {
86
+ if ( typeof paramsOrFunction === 'function' ) {
87
+ if ( paramsOrFunction ( authObject . has ) ) {
65
88
return { ...authObject } ;
66
89
}
67
- notFound ( ) ;
90
+ return handleUnauthorized ( ) ;
68
91
}
69
92
70
93
/**
71
94
* Checking if user is authorized when permission or role is passed
72
95
*/
73
- if ( authObject . has ( params ) ) {
96
+ if ( authObject . has ( paramsOrFunction ) ) {
74
97
return { ...authObject } ;
75
98
}
76
99
77
- notFound ( ) ;
100
+ return handleUnauthorized ( ) ;
78
101
} ;
79
102
80
103
return authObject as AuthSignedIn | AuthSignedOut ;
0 commit comments