From 644480182d8da2ca1197c919262d5a5df0817d25 Mon Sep 17 00:00:00 2001 From: devthejo Date: Sun, 29 Jun 2025 18:42:58 +0200 Subject: [PATCH] fix(headless): use axios instead of apollo for auth --- src/auth/actions.js | 64 +++++++++++++++++++++++---------- src/auth/gql.js | 7 ++++ src/network/NetworkProviders.js | 4 ++- src/network/axios.js | 13 ++++++- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/auth/actions.js b/src/auth/actions.js index 86b7381..14aab4a 100644 --- a/src/auth/actions.js +++ b/src/auth/actions.js @@ -1,40 +1,68 @@ import * as Device from "expo-device"; import network from "~/network"; +import env from "~/env"; import { - REGISTER_USER_MUTATION, - LOGIN_USER_TOKEN_MUTATION, STORE_FCM_TOKEN_MUTATION, + REGISTER_USER_MUTATION_STRING, + LOGIN_USER_TOKEN_MUTATION_STRING, } from "~/auth/gql"; import { getDeviceUuid } from "./deviceUuid"; +// to support refresh auth in headless mode we'll use axios instead of apollo +// read more https://github.com/transistorsoft/react-native-background-fetch/issues/562 + export async function registerUser() { - const { data } = await network.apolloClient.mutate({ - mutation: REGISTER_USER_MUTATION, - context: { - skipAuth: true, // Skip adding Authorization header + const { data } = await network.axios.post( + env.GRAPHQL_URL, + { + query: REGISTER_USER_MUTATION_STRING, }, - }); - const authToken = data.addOneAuthInitToken.authTokenJwt; + { + headers: { + // Skip adding Authorization header for this request + Authorization: undefined, + }, + }, + ); + + if (data.errors && data.errors.length > 0) { + const message = data.errors.map((err) => err.message).join("; "); + throw new Error(`GraphQL Error: ${message}`); + } + + const authToken = data.data.addOneAuthInitToken.authTokenJwt; return { authToken }; } export async function loginUserToken({ authToken }) { const deviceUuid = await getDeviceUuid(); - const { data } = await network.apolloClient.mutate({ - mutation: LOGIN_USER_TOKEN_MUTATION, - variables: { - authTokenJwt: authToken, - phoneModel: Device.modelName, - deviceUuid, + const { data } = await network.axios.post( + env.GRAPHQL_URL, + { + query: LOGIN_USER_TOKEN_MUTATION_STRING, + variables: { + authTokenJwt: authToken, + phoneModel: Device.modelName, + deviceUuid, + }, }, - context: { - skipAuth: true, // Skip adding Authorization header + { + headers: { + // Skip adding Authorization header for this request + Authorization: undefined, + }, }, - }); - const userToken = data.doAuthLoginToken.userBearerJwt; + ); + + if (data.errors && data.errors.length > 0) { + const message = data.errors.map((err) => err.message).join("; "); + throw new Error(`GraphQL Error: ${message}`); + } + + const userToken = data.data.doAuthLoginToken.userBearerJwt; return { userToken }; } diff --git a/src/auth/gql.js b/src/auth/gql.js index 36dbc19..e9e3bf3 100644 --- a/src/auth/gql.js +++ b/src/auth/gql.js @@ -1,4 +1,5 @@ import { gql } from "@apollo/client"; +import { print } from "graphql"; export const REGISTER_USER_MUTATION = gql` mutation registerUser { @@ -36,3 +37,9 @@ export const STORE_FCM_TOKEN_MUTATION = gql` } } `; + +// Convert GraphQL documents to strings for Axios requests +export const REGISTER_USER_MUTATION_STRING = print(REGISTER_USER_MUTATION); +export const LOGIN_USER_TOKEN_MUTATION_STRING = print( + LOGIN_USER_TOKEN_MUTATION, +); diff --git a/src/network/NetworkProviders.js b/src/network/NetworkProviders.js index 7fdc06e..43156ef 100644 --- a/src/network/NetworkProviders.js +++ b/src/network/NetworkProviders.js @@ -5,7 +5,7 @@ import { ApolloProvider } from "@apollo/client"; import createApolloClient from "~/network/apollo"; -// import createAxios from "~/network/axios"; +import createAxios from "~/network/axios"; import createKy from "~/network/ky"; import network from "~/network"; @@ -41,6 +41,8 @@ initializeNewApolloClient(); const oaFilesKy = createKy({ prefixUrl: env.OA_FILES_URL + "/" }, { store }); network.oaFilesKy = oaFilesKy; +network.axios = createAxios(); + export default function NetworkProviders({ children }) { const [key, setKey] = useState(0); diff --git a/src/network/axios.js b/src/network/axios.js index 43e2660..8df8c30 100644 --- a/src/network/axios.js +++ b/src/network/axios.js @@ -24,8 +24,19 @@ export default function createAxios(baseOptions = {}) { "Content-Type": "application/json", }, }; - setBearerHeader(defaultConfig.headers, getAuthState().userToken); + + // Only add bearer token if Authorization header is not explicitly set to undefined + if (config.headers.Authorization !== undefined) { + setBearerHeader(defaultConfig.headers, getAuthState().userToken); + } + defaultsDeep(config, defaultConfig); + + // Clean up undefined Authorization header + if (config.headers.Authorization === undefined) { + delete config.headers.Authorization; + } + return config; }, function (error) {