fix(headless): use axios instead of apollo for auth

This commit is contained in:
devthejo 2025-06-29 18:42:58 +02:00
parent bf957ba115
commit 644480182d
4 changed files with 68 additions and 20 deletions

View file

@ -1,40 +1,68 @@
import * as Device from "expo-device"; import * as Device from "expo-device";
import network from "~/network"; import network from "~/network";
import env from "~/env";
import { import {
REGISTER_USER_MUTATION,
LOGIN_USER_TOKEN_MUTATION,
STORE_FCM_TOKEN_MUTATION, STORE_FCM_TOKEN_MUTATION,
REGISTER_USER_MUTATION_STRING,
LOGIN_USER_TOKEN_MUTATION_STRING,
} from "~/auth/gql"; } from "~/auth/gql";
import { getDeviceUuid } from "./deviceUuid"; 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() { export async function registerUser() {
const { data } = await network.apolloClient.mutate({ const { data } = await network.axios.post(
mutation: REGISTER_USER_MUTATION, env.GRAPHQL_URL,
context: { {
skipAuth: true, // Skip adding Authorization header 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 }; return { authToken };
} }
export async function loginUserToken({ authToken }) { export async function loginUserToken({ authToken }) {
const deviceUuid = await getDeviceUuid(); const deviceUuid = await getDeviceUuid();
const { data } = await network.apolloClient.mutate({ const { data } = await network.axios.post(
mutation: LOGIN_USER_TOKEN_MUTATION, env.GRAPHQL_URL,
variables: { {
authTokenJwt: authToken, query: LOGIN_USER_TOKEN_MUTATION_STRING,
phoneModel: Device.modelName, variables: {
deviceUuid, 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 }; return { userToken };
} }

View file

@ -1,4 +1,5 @@
import { gql } from "@apollo/client"; import { gql } from "@apollo/client";
import { print } from "graphql";
export const REGISTER_USER_MUTATION = gql` export const REGISTER_USER_MUTATION = gql`
mutation registerUser { 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,
);

View file

@ -5,7 +5,7 @@ import { ApolloProvider } from "@apollo/client";
import createApolloClient from "~/network/apollo"; import createApolloClient from "~/network/apollo";
// import createAxios from "~/network/axios"; import createAxios from "~/network/axios";
import createKy from "~/network/ky"; import createKy from "~/network/ky";
import network from "~/network"; import network from "~/network";
@ -41,6 +41,8 @@ initializeNewApolloClient();
const oaFilesKy = createKy({ prefixUrl: env.OA_FILES_URL + "/" }, { store }); const oaFilesKy = createKy({ prefixUrl: env.OA_FILES_URL + "/" }, { store });
network.oaFilesKy = oaFilesKy; network.oaFilesKy = oaFilesKy;
network.axios = createAxios();
export default function NetworkProviders({ children }) { export default function NetworkProviders({ children }) {
const [key, setKey] = useState(0); const [key, setKey] = useState(0);

View file

@ -24,8 +24,19 @@ export default function createAxios(baseOptions = {}) {
"Content-Type": "application/json", "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); defaultsDeep(config, defaultConfig);
// Clean up undefined Authorization header
if (config.headers.Authorization === undefined) {
delete config.headers.Authorization;
}
return config; return config;
}, },
function (error) { function (error) {