Facing Error setting up TiddlyWiki with Firebase cors/api endpoint?

I am following https://neumark.github.io/tw5-firebase/authentication_and_permissions.html with setting up my own wiki and running into this issue. I already got the deployment to work, and set myself as the admin. But the recipe api link might not be correct. Does anyone have any ideas as to what it should be or what i am doing wrong?

etc/config.production.json
this is a snippet of the config file where this url is built
“wiki”: {
“wikiName”: “kronako-wiki”,
“recipe”: “default”,
“apiEndpoint”: “https://us-central1-kronako-wiki.cloudfunctions.net/wiki/
},
also tried curl -i https://us-central1-kronako-wiki.cloudfunctions.net/wiki/recipes which outputs

Cannot GET /recipes

though this might be auth protected

after a fair bit of changes, it is now working

diff --git a/build/schemabuilder.js b/build/schemabuilder.js
index e7589bb..20722ec 100644
--- a/build/schemabuilder.js
+++ b/build/schemabuilder.js
@@ -7,13 +7,19 @@ const relativePath = f => path.resolve(__dirname, "..", f);
 
 const tsconfig = relativePath("tsconfig.json");
 
-for(let {input, output, type} of schemas) {
+for (let { input, output, type } of schemas) {
+    console.log("Generating schema for:", { input, output, type });
     const config = {
         path: relativePath(input),
         tsconfig,
         type
     };
-    const schema = tsj.createGenerator(config).createSchema(config.type);
-    const schemaString = JSON.stringify(schema, null, 2);
-    fs.writeFileSync(relativePath(output), schemaString);
+    try {
+        const schema = tsj.createGenerator(config).createSchema(config.type);
+        const schemaString = JSON.stringify(schema, null, 2);
+        console.log(`Writing schema to ${relativePath(output)}`);
+        fs.writeFileSync(relativePath(output), schemaString);
+    } catch (error) {
+        console.error(`Error generating schema for ${type}:`, error);
+    }
 }

diff --git a/etc/firestore.rules b/etc/firestore.rules
index abd5a65..e5675e7 100644
--- a/etc/firestore.rules
+++ b/etc/firestore.rules
@@ -13,10 +13,12 @@ service cloud.firestore {
         function hasAccessByRole() {
           // don't allow access to personal bags in this match clause
           let isPersonalBag = bagName.matches('^user%3A.*');
-          // anybody with at least reader can read non-personal bags
-          let allowedByRole = get(/databases/$(database)/documents/wikis/$(wikiName)/users/$(request.auth.uid)).data.role >= 2;
+          // Verify role exists and is valid
+          let allowedByRole = exists(/databases/$(database)/documents/wikis/$(wikiName)/users/$(request.auth.uid)) && 
+                              get(/databases/$(database)/documents/wikis/$(wikiName)/users/$(request.auth.uid)).data.role >= 2;
           return !isPersonalBag && allowedByRole;
         }
+
         allow get, list: if request.auth != null && hasAccessByRole();
     }
   }
diff --git a/firebase.production.json b/firebase.production.json
index 9758800..2eaa7b1 100644
--- a/firebase.production.json
+++ b/firebase.production.json
@@ -7,7 +7,7 @@
   },
   "hosting": [
     {
-      "site": "pn-wiki",
+      "site": "kronako-wiki",
       "public": "public",
       "redirects": [{
           "source": "/static/:file*",
diff --git a/package.json b/package.json
index ac5c55f..b1c1e93 100644
--- a/package.json
+++ b/package.json
@@ -58,11 +58,15 @@
     "yargs": "^16.2.0"
   },
   "dependencies": {
+    "@js-sdsl/ordered-map": "^4.4.2",
+    "@types/helmet": "^0.0.48",
     "ajv": "^7.2.1",
     "cors": "^2.8.5",
     "express": "^4.17.1",
+    "express-rate-limit": "^7.5.0",
     "firebase-admin": "^9.5.0",
     "firebase-functions": "^3.13.2",
+    "helmet": "^8.0.0",
     "inversify": "^5.0.5",
     "reflect-metadata": "^0.1.13",
     "source-map-support": "^0.5.19"
     
diff --git a/src/backend/api/endpoints.ts b/src/backend/api/endpoints.ts
index 9a5d608..4540f34 100644
--- a/src/backend/api/endpoints.ts
+++ b/src/backend/api/endpoints.ts
@@ -20,7 +20,7 @@
  */
 
 import cors from 'cors';
-import * as express from 'express';
+import express from 'express';
 import { inject, injectable } from 'inversify';
 import { TW5FirebaseError, TW5FirebaseErrorCode } from '../../shared/model/errors';
 import { SingleWikiNamespacedTiddler } from '../../shared/model/store';
@@ -160,18 +160,61 @@ export class APIEndpointFactory {
     }
 
     createAPI() {
-        const api = express.default();
-        api.use(cors({ origin: true }));
+        const api = express();
+        
+        // CORS middleware
+        api.use(cors({ 
+            origin: 'https://kronako-wiki.web.app', 
+            methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
+            allowedHeaders: 'Authorization, Content-Type, Accept',
+            optionsSuccessStatus: 204 
+        }));
+        
+        // Preflight request handling
+        api.options('*', (req, res) => {
+            res.set({
+                'Access-Control-Allow-Origin': 'https://kronako-wiki.web.app',
+                'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
+                'Access-Control-Allow-Headers': 'Authorization, Content-Type, Accept',
+            });
+            res.status(204).send(); // Respond with no content
+        });
+    
+        // Add CORS headers to all responses
+        api.use((req, res, next) => {
+            res.set('Access-Control-Allow-Origin', 'https://kronako-wiki.web.app');
+            next();
+        });
+    
+        // Authorization header validation
+        api.use((req, res, next) => {
+            if (req.headers.authorization) {
+                next(); // Authorization logic passes
+            } else {
+                res.status(401).send("Authorization header is required");
+            }
+        });
+    
+        // Attach middleware
         api.use(this.authenticatorMiddleware.authenticate.bind(this.authenticatorMiddleware));
+    
+        // Bind endpoints
         const read = this.bindAndSerialize(this.read);
         const write = this.bindAndSerialize(this.write);
         api.get('/:wiki/recipes/:recipe/tiddlers/:title?', read);
         api.get('/:wiki/bags/:bag/tiddlers/:title?', read);
-        api.put('/:wiki/recipes/:recipe/tiddlers/:title', write); // create
-        api.put('/:wiki/recipes/:recipe/tiddlers/:title/revisions/:revision', write); // update
-        api.put('/:wiki/bags/:bag/tiddlers/:title', write); // create
-        api.put('/:wiki/bags/:bag/tiddlers/:title/revisions/:revision', write); // update
+        api.put('/:wiki/recipes/:recipe/tiddlers/:title', write);
+        api.put('/:wiki/recipes/:recipe/tiddlers/:title/revisions/:revision', write);
+        api.put('/:wiki/bags/:bag/tiddlers/:title', write);
+        api.put('/:wiki/bags/:bag/tiddlers/:title/revisions/:revision', write);
         api.delete('/:wiki/bags/:bag/tiddlers/:title/revisions/:revision', this.bindAndSerialize(this.remove));
+    
+        // Error handling middleware
+        api.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
+            console.error(err.stack);
+            res.status(err.status || 500).send(err.message || 'Internal Server Error');
+        });
+    
         return api;
     }
 }
diff --git a/src/backend/api/policy-checker.ts b/src/backend/api/policy-checker.ts
index 1d6121b..6d09ada 100644
--- a/src/backend/api/policy-checker.ts
+++ b/src/backend/api/policy-checker.ts
@@ -105,7 +105,7 @@ export class PolicyChecker {
         return {
             ...bagPermission,
             allowed,
-            reason: allowed ? undefined : PolicyRejectReason.CONTRAINTS,
+            reason: allowed ? undefined : PolicyRejectReason.CONSTRAINTS,
         };
     }
 
diff --git a/src/backend/index.ts b/src/backend/index.ts
index c695660..1bf9b61 100644
--- a/src/backend/index.ts
+++ b/src/backend/index.ts
@@ -2,16 +2,49 @@
 import 'reflect-metadata';
 import 'source-map-support/register';
 import * as functions from 'firebase-functions';
+import cors from 'cors';
+import express, { RequestHandler } from 'express';
 import { productionStartup } from './common/startup';
 import { Component } from './common/ioc/components';
 import { Config } from '../shared/model/config';
 import { APIEndpointFactory } from './api/endpoints';
 
+// Initialize the IoC container and components
 const container = productionStartup();
 const apiEndpointFactory = container.get<APIEndpointFactory>(Component.APIEndpointFactory);
+const config = container.get<Config>(Component.config);
 
+// Create an Express app and apply middleware
+const app = express();
+
+// Define CORS options
+const corsOptions = {
+  origin: 'https://kronako-wiki.web.app', // Replace with your allowed origin
+  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
+  allowedHeaders: 'Authorization, Content-Type, X-Requested-With, Accept',
+  optionsSuccessStatus: 204,
+};
+
+
+// Apply CORS middleware with explicit type casting
+const corsMiddleware = cors(corsOptions) as RequestHandler;
+app.use(corsMiddleware);
+app.options('*', corsMiddleware);
+
+// Attach the API endpoints to the Express app
+app.use('/api', apiEndpointFactory.createAPI());
+
+// Add a logging middleware for debugging
+app.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
+  console.log(`[${req.method}] ${req.url}`);
+  console.log(`Headers:`, req.headers);
+  next();
+});
+
+// Export the Firebase Function
 export const wiki = functions
-    .region(container.get<Config>(Component.config).deploy.apiRegion)
-    .runWith({
-      timeoutSeconds: 540
-    }).https.onRequest(apiEndpointFactory.createAPI());
+  .region(config.deploy.apiRegion)
+  .runWith({
+    timeoutSeconds: 540,
+  })
+  .https.onRequest(app);

diff --git a/src/shared/model/bag-policy.ts b/src/shared/model/bag-policy.ts
index c4fe154..fdd610e 100644
--- a/src/shared/model/bag-policy.ts
+++ b/src/shared/model/bag-policy.ts
@@ -8,7 +8,7 @@ export type BagPolicy = { [key in AccessType]: Grantee[] } & { constraints?: str
 
 export enum PolicyRejectReason {
     INSUFFICIENT_PERMISSION = 'insufficient_permissions',
-    CONTRAINTS = 'constraints',
+    CONSTRAINTS = 'constraints',
 }
 
 export const standardPolicies: { [bag: string]: BagPolicy } = {

diff --git a/tsconfig.json b/tsconfig.json
index 4065bab..11aec7d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -23,6 +23,7 @@
     "typeRoots": ["node_modules/@types"],
     "noUnusedLocals": true,
     "noImplicitReturns": true,
+    "allowSyntheticDefaultImports": true,
     "noFallthroughCasesInSwitch": true
   },
   "include": ["src", "generated"],

and had to update the config.production.json to "apiEndpoint": "https://us-central1-kronako-wiki.cloudfunctions.net/wiki/api/"