1- import { PropsWithChildren , useCallback , useEffect , useMemo , useState } from 'react' ;
2- import { useLocation , useNavigate } from 'react-router-dom' ;
1+ import { PropsWithChildren , useCallback , useMemo , useState } from 'react' ;
32import {
43 clearNotifyCompRemoteToken ,
5- consumeNotifyCompRemoteRedirectPath ,
64 getNotifyCompRemoteClaims ,
75 getNotifyCompRemoteToken ,
8- isNotifyCompRemoteAuthPending ,
9- setNotifyCompRemoteAuthPending ,
6+ hasNotifyCompRemoteTokenForCompetition ,
107 setNotifyCompRemoteToken ,
118} from '@/lib/notifyCompRemoteAuth' ;
12- import { NOTIFYCOMP_AUTH_ORIGIN } from '@/lib/remoteConfig' ;
9+ import { getStoredWcaAccessToken } from '@/lib/wcaAccessToken' ;
10+ import { useAuth } from '../AuthProvider' ;
1311import { NotifyCompRemoteAuthContext } from './NotifyCompRemoteAuthContext' ;
1412
13+ const NOTIFY_COMP_TOKEN_URL = '/.netlify/functions/notify-comp-token' ;
14+ const REMOTE_SCOPE = 'notifycomp.remote' ;
15+
1516const readErrorMessage = async ( response : Response ) => {
1617 const text = await response . text ( ) ;
1718
@@ -27,82 +28,67 @@ export function NotifyCompRemoteAuthProvider({ children }: PropsWithChildren) {
2728 const [ token , setToken ] = useState ( getNotifyCompRemoteToken ) ;
2829 const [ authenticating , setAuthenticating ] = useState ( false ) ;
2930 const [ error , setError ] = useState < string | null > ( null ) ;
30- const location = useLocation ( ) ;
31- const navigate = useNavigate ( ) ;
32-
33- const signIn = useCallback ( ( ) => {
34- const redirectPath = `${ window . location . pathname } ${ window . location . search } ${ window . location . hash } ` ;
35- setNotifyCompRemoteAuthPending ( redirectPath ) ;
36- setError ( null ) ;
37-
38- const params = new URLSearchParams ( {
39- redirect_uri : window . location . href ,
40- } ) ;
41-
42- window . location . href = `${ NOTIFYCOMP_AUTH_ORIGIN } /auth/wca?${ params . toString ( ) } ` ;
43- } , [ ] ) ;
44-
45- const signOut = useCallback ( ( ) => {
46- clearNotifyCompRemoteToken ( ) ;
47- setToken ( null ) ;
48- } , [ ] ) ;
49-
50- useEffect ( ( ) => {
51- const params = new URLSearchParams ( location . search ) ;
52- const code = params . get ( 'code' ) ;
31+ const { signIn : signInWithWca } = useAuth ( ) ;
32+
33+ const signIn = useCallback (
34+ async ( competitionId : string ) => {
35+ setError ( null ) ;
36+ const accessToken = getStoredWcaAccessToken ( ) ;
37+
38+ if ( ! accessToken ) {
39+ signInWithWca ( ) ;
40+ return ;
41+ }
42+
43+ setAuthenticating ( true ) ;
44+
45+ try {
46+ const response = await fetch ( NOTIFY_COMP_TOKEN_URL , {
47+ method : 'POST' ,
48+ headers : {
49+ 'Content-Type' : 'application/json' ,
50+ } ,
51+ body : JSON . stringify ( {
52+ accessToken,
53+ competitionId,
54+ scope : REMOTE_SCOPE ,
55+ } ) ,
56+ } ) ;
5357
54- if ( ! code || ! isNotifyCompRemoteAuthPending ( ) ) {
55- return ;
56- }
57-
58- setAuthenticating ( true ) ;
59- setError ( null ) ;
60-
61- const callbackParams = new URLSearchParams ( {
62- code,
63- redirect_uri : window . location . href ,
64- } ) ;
65-
66- fetch ( `${ NOTIFYCOMP_AUTH_ORIGIN } /auth/wca/callback?${ callbackParams . toString ( ) } ` )
67- . then ( async ( response ) => {
6858 if ( ! response . ok ) {
6959 throw new Error ( await readErrorMessage ( response ) ) ;
7060 }
7161
72- return ( await response . json ( ) ) as { jwt ?: string } ;
73- } )
74- . then ( ( { jwt } ) => {
75- if ( ! jwt ) {
76- throw new Error ( 'NotifyComp did not return a remote session token.' ) ;
62+ const payload = ( await response . json ( ) ) as { token ?: string } ;
63+ if ( ! payload . token ) {
64+ throw new Error ( 'Remote token response was missing a token.' ) ;
7765 }
7866
79- setNotifyCompRemoteToken ( jwt ) ;
80- setToken ( jwt ) ;
81-
82- const nextParams = new URLSearchParams ( location . search ) ;
83- nextParams . delete ( 'code' ) ;
84- const query = nextParams . toString ( ) ;
85- const fallbackPath = `${ location . pathname } ${ query ? `?${ query } ` : '' } ${ location . hash } ` ;
86- const redirectPath = consumeNotifyCompRemoteRedirectPath ( ) || fallbackPath ;
87- navigate ( redirectPath , { replace : true } ) ;
88- } )
89- . catch ( ( err ) => {
90- setError ( err instanceof Error ? err . message : 'Unable to sign in to NotifyComp Remote.' ) ;
67+ setNotifyCompRemoteToken ( payload . token ) ;
68+ setToken ( payload . token ) ;
69+ } catch ( err ) {
70+ setError ( err instanceof Error ? err . message : 'Unable to authorize NotifyComp Remote.' ) ;
9171 clearNotifyCompRemoteToken ( ) ;
9272 setToken ( null ) ;
93- consumeNotifyCompRemoteRedirectPath ( ) ;
94- } )
95- . finally ( ( ) => {
73+ } finally {
9674 setAuthenticating ( false ) ;
97- } ) ;
98- } , [ location , navigate ] ) ;
75+ }
76+ } ,
77+ [ signInWithWca ] ,
78+ ) ;
79+
80+ const signOut = useCallback ( ( ) => {
81+ clearNotifyCompRemoteToken ( ) ;
82+ setToken ( null ) ;
83+ } , [ ] ) ;
9984
10085 const claims = token ? getNotifyCompRemoteClaims ( ) : null ;
10186
10287 const value = useMemo (
10388 ( ) => ( {
10489 authenticating,
10590 error,
91+ isAuthenticatedForCompetition : hasNotifyCompRemoteTokenForCompetition ,
10692 isAuthenticated : Boolean ( token ) ,
10793 signIn,
10894 signOut,
0 commit comments