2024-07-11 18:16:18 +02:00
|
|
|
import { ApiError } from '@/api/ApiError'
|
|
|
|
|
import { fetchApi } from '@/api/fetchApi'
|
|
|
|
|
import { type ApiUser } from './ApiUser'
|
2024-07-25 18:08:10 +02:00
|
|
|
import { attemptSilentLogin, canAttemptSilentLogin } from '../utils/silentLogin'
|
2024-07-11 18:16:18 +02:00
|
|
|
|
|
|
|
|
/**
|
2024-07-17 16:19:15 +02:00
|
|
|
* fetch the logged-in user from the api.
|
2024-07-11 18:16:18 +02:00
|
|
|
*
|
|
|
|
|
* If the user is not logged in, the api returns a 401 error.
|
|
|
|
|
* Here our wrapper just returns false in that case, without triggering an error:
|
|
|
|
|
* this is done to prevent unnecessary query retries with react query
|
|
|
|
|
*/
|
2025-02-10 16:34:16 +01:00
|
|
|
export const fetchUser = (
|
|
|
|
|
opts: {
|
|
|
|
|
attemptSilent?: boolean
|
|
|
|
|
} = {
|
|
|
|
|
attemptSilent: true,
|
|
|
|
|
}
|
|
|
|
|
): Promise<ApiUser | false> => {
|
2024-07-11 18:16:18 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
fetchApi<ApiUser>('/users/me')
|
|
|
|
|
.then(resolve)
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
// we assume that a 401 means the user is not logged in
|
|
|
|
|
if (error instanceof ApiError && error.statusCode === 401) {
|
2024-07-25 18:08:10 +02:00
|
|
|
// make sure to not resolve the promise while trying to silent login
|
|
|
|
|
// so that consumers of fetchUser don't think the work already ended
|
2025-02-10 16:34:16 +01:00
|
|
|
if (opts.attemptSilent && canAttemptSilentLogin()) {
|
2025-04-28 13:18:33 +02:00
|
|
|
attemptSilentLogin(30)
|
2024-07-25 18:08:10 +02:00
|
|
|
} else {
|
|
|
|
|
resolve(false)
|
|
|
|
|
}
|
2024-07-11 18:16:18 +02:00
|
|
|
} else {
|
|
|
|
|
reject(error)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|