@@ -10,44 +10,41 @@ import { createFunctionsModule } from "./modules/functions.js";
1010 * @param {Object } config - Client configuration
1111 * @param {string } [config.serverUrl='https://base44.app'] - API server URL
1212 * @param {string|number } config.appId - Application ID
13- * @param {string } [config.env='prod'] - Environment ('prod' or 'dev')
1413 * @param {string } [config.token] - Authentication token
14+ * @param {string } [config.serviceToken] - Service role authentication token
1515 * @param {boolean } [config.requiresAuth=false] - Whether the app requires authentication
1616 * @returns {Object } Base44 client instance
1717 */
1818export function createClient ( config : {
1919 serverUrl ?: string ;
2020 appId : string ;
21- env ?: string ;
2221 token ?: string ;
22+ serviceToken ?: string ;
2323 requiresAuth ?: boolean ;
2424} ) {
2525 const {
2626 serverUrl = "https://base44.app" ,
2727 appId,
28- env = "prod" ,
2928 token,
29+ serviceToken,
3030 requiresAuth = false ,
3131 } = config ;
3232
33- // Create the base axios client
3433 const axiosClient = createAxiosClient ( {
3534 baseURL : `${ serverUrl } /api` ,
3635 headers : {
3736 "X-App-Id" : String ( appId ) ,
38- "X-Environment" : env ,
3937 } ,
4038 token,
41- requiresAuth, // Pass requiresAuth to axios client
42- appId, // Pass appId for login redirect
43- serverUrl, // Pass serverUrl for login redirect
39+ requiresAuth,
40+ appId,
41+ serverUrl,
4442 } ) ;
4543
4644 const functionsAxiosClient = createAxiosClient ( {
4745 baseURL : `${ serverUrl } /api` ,
4846 headers : {
4947 "X-App-Id" : String ( appId ) ,
50- "X-Environment" : env ,
5148 } ,
5249 token,
5350 requiresAuth,
@@ -56,18 +53,46 @@ export function createClient(config: {
5653 interceptResponses : false ,
5754 } ) ;
5855
59- // Create modules
60- const entities = createEntitiesModule ( axiosClient , appId ) ;
61- const integrations = createIntegrationsModule ( axiosClient , appId ) ;
62- const auth = createAuthModule ( axiosClient , appId , serverUrl ) ;
63- const functions = createFunctionsModule ( functionsAxiosClient , appId ) ;
56+ const serviceRoleAxiosClient = createAxiosClient ( {
57+ baseURL : `${ serverUrl } /api` ,
58+ headers : {
59+ "X-App-Id" : String ( appId ) ,
60+ } ,
61+ token : serviceToken ,
62+ serverUrl,
63+ appId,
64+ } ) ;
65+
66+ const serviceRoleFunctionsAxiosClient = createAxiosClient ( {
67+ baseURL : `${ serverUrl } /api` ,
68+ headers : {
69+ "X-App-Id" : String ( appId ) ,
70+ } ,
71+ token : serviceToken ,
72+ serverUrl,
73+ appId,
74+ interceptResponses : false ,
75+ } ) ;
76+
77+ const userModules = {
78+ entities : createEntitiesModule ( axiosClient , appId ) ,
79+ integrations : createIntegrationsModule ( axiosClient , appId ) ,
80+ auth : createAuthModule ( axiosClient , functionsAxiosClient , appId ) ,
81+ functions : createFunctionsModule ( functionsAxiosClient , appId ) ,
82+ } ;
83+
84+ const serviceRoleModules = {
85+ entities : createEntitiesModule ( serviceRoleAxiosClient , appId ) ,
86+ integrations : createIntegrationsModule ( serviceRoleAxiosClient , appId ) ,
87+ functions : createFunctionsModule ( serviceRoleFunctionsAxiosClient , appId ) ,
88+ } ;
6489
6590 // Always try to get token from localStorage or URL parameters
6691 if ( typeof window !== "undefined" ) {
6792 // Get token from URL or localStorage
6893 const accessToken = token || getAccessToken ( ) ;
6994 if ( accessToken ) {
70- auth . setToken ( accessToken ) ;
95+ userModules . auth . setToken ( accessToken ) ;
7196 }
7297 }
7398
@@ -76,30 +101,27 @@ export function createClient(config: {
76101 // We perform this check asynchronously to not block client creation
77102 setTimeout ( async ( ) => {
78103 try {
79- const isAuthenticated = await auth . isAuthenticated ( ) ;
104+ const isAuthenticated = await userModules . auth . isAuthenticated ( ) ;
80105 if ( ! isAuthenticated ) {
81- auth . redirectToLogin ( window . location . href ) ;
106+ userModules . auth . redirectToLogin ( window . location . href ) ;
82107 }
83108 } catch ( error ) {
84109 console . error ( "Authentication check failed:" , error ) ;
85- auth . redirectToLogin ( window . location . href ) ;
110+ userModules . auth . redirectToLogin ( window . location . href ) ;
86111 }
87112 } , 0 ) ;
88113 }
89114
90115 // Assemble and return the client
91- return {
92- entities,
93- integrations,
94- auth,
95- functions,
116+ const client = {
117+ ...userModules ,
96118
97119 /**
98120 * Set authentication token for all requests
99121 * @param {string } newToken - New auth token
100122 */
101123 setToken ( newToken : string ) {
102- auth . setToken ( newToken ) ;
124+ userModules . auth . setToken ( newToken ) ;
103125 } ,
104126
105127 /**
@@ -110,9 +132,61 @@ export function createClient(config: {
110132 return {
111133 serverUrl,
112134 appId,
113- env,
114135 requiresAuth,
115136 } ;
116137 } ,
138+
139+ /**
140+ * Access service role modules - throws error if no service token was provided
141+ * @throws {Error } When accessed without a service token
142+ */
143+ get asServiceRole ( ) {
144+ if ( ! serviceToken ) {
145+ throw new Error ( 'Service token is required to use asServiceRole. Please provide a serviceToken when creating the client.' ) ;
146+ }
147+ return serviceRoleModules ;
148+ }
117149 } ;
150+
151+ return client ;
152+ }
153+
154+ export function createClientFromRequest ( request : Request ) {
155+ const authHeader = request . headers . get ( "Authorization" ) ;
156+ const serviceRoleAuthHeader = request . headers . get (
157+ "Base44-Service-Authorization"
158+ ) ;
159+ const appId = request . headers . get ( "Base44-App-Id" ) ;
160+ const serverUrlHeader = request . headers . get ( "Base44-Api-Url" ) ;
161+
162+ if ( ! appId ) {
163+ throw new Error (
164+ "Base44-App-Id header is required, but is was not found on the request"
165+ ) ;
166+ }
167+
168+ // Validate authorization header formats
169+ let serviceRoleToken : string | undefined ;
170+ let userToken : string | undefined ;
171+
172+ if ( serviceRoleAuthHeader !== null ) {
173+ if ( serviceRoleAuthHeader === '' || ! serviceRoleAuthHeader . startsWith ( 'Bearer ' ) || serviceRoleAuthHeader . split ( ' ' ) . length !== 2 ) {
174+ throw new Error ( 'Invalid authorization header format. Expected "Bearer <token>"' ) ;
175+ }
176+ serviceRoleToken = serviceRoleAuthHeader . split ( ' ' ) [ 1 ] ;
177+ }
178+
179+ if ( authHeader !== null ) {
180+ if ( authHeader === '' || ! authHeader . startsWith ( 'Bearer ' ) || authHeader . split ( ' ' ) . length !== 2 ) {
181+ throw new Error ( 'Invalid authorization header format. Expected "Bearer <token>"' ) ;
182+ }
183+ userToken = authHeader . split ( ' ' ) [ 1 ] ;
184+ }
185+
186+ return createClient ( {
187+ serverUrl : serverUrlHeader || "https://base44.app" ,
188+ appId,
189+ token : userToken ,
190+ serviceToken : serviceRoleToken ,
191+ } ) ;
118192}
0 commit comments