Browse Source

dev: add experimental firebase authentication

This adds an experimental custom token authentication endpoint to Puter.
This is disabled unless the firebase-auth service is explicitly
configured, and is not yet ready for production use.
KernelDeimos 2 weeks ago
parent
commit
4647e2d9c0

File diff suppressed because it is too large
+ 720 - 33
package-lock.json


+ 2 - 0
src/backend/exports.js

@@ -44,6 +44,7 @@ const { EntityStoreModule } = require("./src/modules/entitystore/EntityStoreModu
 const { AnalyticsModule } = require("./src/modules/analytics/AnalyticsModule.js");
 const { KVStoreModule } = require("./src/modules/kvstore/KVStoreModule.js");
 const { ExternalExtrasModule } = require("./src/modules/external-extras/ExternalExtrasModule.js");
+const { FirebaseModule } = require("./src/modules/firebase/FirebaseModule.js");
 
 module.exports = {
     helloworld: () => {
@@ -88,6 +89,7 @@ module.exports = {
     ConvertModule,
     CaptchaModule,
     KVStoreModule,
+    FirebaseModule,
     
     // Development modules
     PerfMonModule,

+ 1 - 0
src/backend/package.json

@@ -37,6 +37,7 @@
     "dedent": "^1.5.3",
     "express": "^4.18.2",
     "file-type": "^18.5.0",
+    "firebase-admin": "^13.3.0",
     "form-data": "^4.0.0",
     "groq-sdk": "^0.5.0",
     "handlebars": "^4.7.8",

+ 37 - 0
src/backend/src/modules/firebase/FirebaseAuthService.js

@@ -0,0 +1,37 @@
+const BaseService = require("../../services/BaseService");
+
+const admin = require('firebase-admin');
+const { Endpoint } = require("../../util/expressutil");
+const configurable_auth = require("../../middleware/configurable_auth");
+
+class FirebaseAuthService extends BaseService {
+    async _init () {
+        admin.initializeApp({
+            credential: admin.credential.cert(this.config.serviceAccount),
+        });
+    }
+
+    async ['__on_install.routes'] (_, { app }) {
+        const r_firebase = (() => {
+            const require = this.require;
+            const express = require('express');
+            return express.Router();
+        })();
+
+        Endpoint({
+            route: '/get-token',
+            methods: ['GET'],
+            mw: [configurable_auth()],
+            handler: async (req, res) => {
+                const token = await admin.auth().createCustomToken(req.actor.uid);
+                res.json(token);
+            }
+        }).attach(r_firebase);
+
+        app.use('/firebase', r_firebase);
+    }
+}
+
+module.exports = {
+    FirebaseAuthService,
+};

+ 17 - 0
src/backend/src/modules/firebase/FirebaseModule.js

@@ -0,0 +1,17 @@
+const { AdvancedBase } = require("@heyputer/putility");
+const config = require("../../config");
+
+class FirebaseModule extends AdvancedBase {
+    async install (context) {
+        const services = context.get('services');
+        
+        if ( !! config?.services?.['firebase-auth']) {
+            const { FirebaseAuthService } = require("./FirebaseAuthService");
+            services.registerService('firebase-auth', FirebaseAuthService);
+        }
+    }
+}
+
+module.exports = {
+    FirebaseModule,
+};

+ 6 - 1
src/backend/src/modules/web/WebServerService.js

@@ -359,7 +359,12 @@ class WebServerService extends BaseService {
                 ].join(' ');
 
                 const log = this.services.get('log-service').create('morgan');
-                log.info(message, fields);
+                try {
+                    log.info(message, fields);
+                } catch (e) {
+                    console.log('failed to log this message properly:', message, fields);
+                    console.error(e);
+                }
             }
             };
 

+ 2 - 0
tools/run-selfhosted.js

@@ -93,6 +93,7 @@ const main = async () => {
         MailModule,
         ConvertModule,
         DevelopmentModule,
+        FirebaseModule,
     } = (await import('@heyputer/backend')).default;
 
     const k = new Kernel({
@@ -112,6 +113,7 @@ const main = async () => {
     k.add_module(new ExternalExtrasModule());
     k.add_module(new MailModule());
     k.add_module(new ConvertModule());
+    k.add_module(new FirebaseModule());
     if ( process.env.UNSAFE_PUTER_DEV ) {
         k.add_module(new DevelopmentModule());
     }

Some files were not shown because too many files changed in this diff