Naming Prosecution Mitigator

    @tinypudding/firebase-express-template

    1.2.17 • Public • Published

    Discord server NPM version NPM downloads Patreon Ko-Fi

    npm installnfo

    Firebase-Express-Template

    A template for website development using Firebase.

    Example

    config.json

    These are the Firebase Server settings for the @tinypudding/firebase-lib module and the domain validator from the @tinypudding/puddy-lib.

    {
        "options": {
            "id": "main"
        },
        "firebase": {
            "databaseURL": "example",
            "authDomain": "example.com",
            "serviceAccountId": "example@example.iam.gserviceaccount.com",
        },
        "domain": "example.com"
    }

    firebase_web.json

    These are the Firebase Client settings that are in your website.

    {
        "apiKey": "",
        "authDomain": "example.com",
        "projectId": "example",
        "appId": ""
    }

    index.js

    // Prepare Modules
    const functions = require('firebase-functions');
    const tinyCfg = require('./config.json');
    const expressTemplate = require('@tinypudding/firebase-express-template');
    
    // Get a Custom Firebase Cert
    const isEmulator = require('@tinypudding/firebase-lib/isEmulator');
    if(isEmulator()){
        const admin = require('firebase-admin');
        tinyCfg.firebase.credential = admin.credential.cert(require('./firebase.json'));
    }
    
    // Prepare App
    const app = expressTemplate({
    
        // File Config
        fileCfg: {
            fileMaxAge: '2592000000'
        },
    
        // Error Page
        errorPage: (req, res, data, cfg, firebaseWeb) => {
    
            // Is a Error Page
            if (res && req) {
    
                // Logger
                const logger = require('@tinypudding/firebase-lib/logger');
    
                // Prepare Result
                const result = { code: data.code };
    
                // Get Error Message
                if (data.message) { result.text = data.message; }
                else if (data.err && data.err.message) { result.text = data.err.message; }
                else { result.text = '???'; }
    
                // Log
                if (data.code !== 404) {
                    let errorData = null;
                    if (data.err) { errorData = data.err; }
                    else if (data.message) { errorData = new Error(data.message); }
                    else { errorData = new Error('Unknown Error'); }
                    errorData.code = data.code;
                    logger.error(errorData);
                }
    
                // Send Error Page
                return res.json(result);
    
            } 
            
            // Nothing
            else { return; }
    
        },
    
        // Website Middleware
        middleware: function (web) {
         
            // Nunjucks Module. You can use any module here.
            const path = require('path');
            const nunjucks = require('nunjucks');
            nunjucks.configure(path.join(__dirname, '../views'), {
                autoescape: true,
                express: web.app
            });
    
            web.app.set('view engine', 'nunjucks');
    
            // Homepage (web.dsSession will install the Discord Session in this page)
            web.app.get('/', web.dsSession(), (req, res) => {
                console.log(req.discord_session);
                res.render('test');
                return;
            });
    
            // Install Firebase Google oAuth in this page
            web.app.get('/firebasePage', web.googleFireAuth, (req, res) => {
                console.log(req.firebase_session);
                res.render('test');
                return;
            });
    
            // Complete
            return web.fn();
         
        },
        
        // config.json
        cfg: tinyCfg,
    
        // Helmet
        // https://www.npmjs.com/package/helmet
        helmet: {
            contentSecurityPolicy: {
                directives: {
                    defaultSrc: ["'self'", "'unsafe-inline'", 'https://securetoken.googleapis.com/', 'https://www.googleapis.com/']
                }
            }
        },
    
        // Main
        main: {
            domainValidator: {
    
                // Domain Validator
                domain: tinyCfg.domain, 
    
                // Static Path Protector
                staticPath: ['/css/', '/img/', '/js/', '/sound/', '/webfonts/'] 
    
            }
        },
    
        // Firebase
        firebase: { options: tinyCfg.options, firebase: tinyCfg.firebase },
        firebaseWeb: require('./firebase_web.json'),
    
        // Cookie Session Module Settings
        // https://www.npmjs.com/package/cookie-session
        cookieSession: {
            keys: [
                "FkWS8HFZUt",
                "1EC4RdpUEQ"
            ]
        },
    
        // csrftoken
        // https://www.npmjs.com/package/@tinypudding/csrftoken-lib
        csrftoken: {
    
            // This is the path of the module method ( csrftoken(csrfToken', 1, 'hours'); )
            module: ['csrfToken', 1, 'hours'],
    
            // The Callback of the Csrf Token validator for all other modules of the template.
            callback: function (req) {
            
                // Prepare Result
                const result = { now: null, server: null };
    
                // Get Body
                if(req.body && typeof req.body.csrftoken === "string") { result.now = req.body.csrftoken; }
    
                // Get Server
                if(req.csrfToken && req.csrfToken.now && typeof req.csrfToken.now.value === "string") { result.server = req.csrfToken.now.value; }
    
                // Send Reuslt
                return result; 
            
            }
    
        },
    
        // Timezone Module (You need the module cookie-session installed)
        // https://www.npmjs.com/package/@tinypudding/timezone-cookie-session
        timezone: {
            urls: { setTime: '/setTime' },
            clock24: true,
            autoList: true,
            setSecondary: true,
            fileMaxAge: '2592000000'
        },
    
        // i18 Module  (You need the module cookie-session installed)
        // https://www.npmjs.com/package/@tinypudding/i18
        i18: {
    
            // Vars Session Names.
            cfg: {
    
                // Vars cookie-session.
                varsSession: {
                    sessionLang: 'sessionLang',
                    userLang: 'userLang',
                    nowLang: 'nowLang',
                    langIsUser: 'langIsUser'
                },
    
                // Lang List.
                list: [
                    { value: 'en', name: 'English' },
                    { value: 'pt-br', name: 'Português Brasil' }
                ]
    
            },
    
            // Return true or false if your web session is a logged user.
            getIsUser: function(req, res) {
    
                // Set the user session boolean to false
                return false;
    
            },
    
            // Get CSRF Token
            getCsrfToken: function (req, res) {
                return new Promise(function (resolve) {
    
                    // Return csrfToken
                    resolve({
                        now: '', // CSRF Token sent by the user
                        server: '' // Server CSRF Token
                    });
    
                    // Complete
                    return;
    
                });
            },
    
            // URLs of the module.
            urls: {
                setLang: '/setLang'
            },
    
        },
    
        /* 
        
            Discord OAuth2 (You need the module cookie-session installed)
    
            If you insert a bot token and have Discord.JS (https://discord.js.org/) installed, req.discord_session.bot will return a Discord.JS Client. 
            
            Do not forget that this Discord.JS Client is not connected to webSockets so as not to allow your Firebase application to be trying to make various Websocket connections with each request on your website.
    
            To start Discord.JS in your application you need to call the method req.discord_session.bot().
            When this method is called, it will transform req.discord_session.bot into a Discord.JS Client.
            If the Discord.JS module is not detected, it will return the module's default methods in the req.discord_session.bot.
    
            https://www.npmjs.com/package/@tinypudding/discord-oauth2
        
        */
        discordOAuth2: {
    
            // Database to get the bot data
            database: {
                
                // Bot Path
                botPath: 'bots',
    
                // App Path
                appPath: 'apps',
    
                // Database Name
                name: 'tiny-boop',
                
                // Paths that are authorized to read the database to obtain the Auth without needing the user logged on. You can use the value "*" to allow the entire website.
                pathNoUser: [],
            
            },
    
            // Localhost to test
            localhost: 'localhost:5000',
    
            // Base
            discord: {
    
                // Discord URL
                url: {
                    commandLogin: '/commandLogin',
                    botLogin: '/botLogin',
                    login: '/login',
                    logout: '/logout',
                    redirect: '/redirect',
                    firebaseLogin: '/firebase/login',
                    firebaseLogout: '/firebase/logout'
                },
    
                // Auth. If you don't set any database values to get the values automatically, the values written here will be used. You must at least enter the discordScope. 
                auth: {
                    bot_token: '',
                    client_id: '',
                    client_secret: '',
                    discordScope: ['identify', 'email'],
                    first_get_user: true
                },
    
                // Crypto Key
                crypto: { key: 'tinypudding123456789012345678900' },
    
                // Check Auth Time
                checkAuthTime: (decodedIdToken) => {
    
                    // Only process if the user just signed in in the last 5 minutes.
                    if (new Date().getTime() / 1000 - decodedIdToken.auth_time < 5 * 60) {
                        return true;
                    }
    
                    // Nope
                    else { return false; }
    
                },
    
                // Cookie Time Generator
                cookieTimeGenerator: (decodedIdToken) => {
    
                    // Set session expiration to 5 days.
                    const expiresIn = 60 * 60 * 24 * 5 * 1000;
    
                    // Complete
                    return expiresIn;
    
                },
    
                // Configuration
                cfg: {
    
                    // Need Email Verification to login in 
                    needEmailVerified: true,
    
                    // Firebase Login Redirect
                    redirect: {
    
                        /* Login */
                        login: function (data, req, res, firebaseCfg, webCfg) {
    
                            // res.render is a Render Module from Nunjucks
                            return res.render('firebase_redirect/login', {
    
                                // the Firebase Web Config to insert in the page.
                                firebase_cfg: JSON.stringify(firebaseCfg),
    
                                // The main function string to be send to login page.
                                start_login: data.functions.run,
    
                                // The Firebase token to do the login.
                                token: data.token,
    
                                // The Csrf Token
                                key: data.key,
    
                                // The Final Redirect URL
                                redirect_url: data.redirect
                                
                            });
    
                        },
    
                        /* Logout */
                        logout: function (data, req, res, firebaseCfg, webCfg) {
    
                            // res.render is a Render Module from Nunjucks
                            return res.render('firebase_redirect/logout', {
    
                                // the Firebase Web Config to insert in the page.
                                firebase_cfg: JSON.stringify(firebaseCfg),
    
                                // The main function string to be send to logout page.
                                start_logout: data.functions.run,
    
                                // The Firebase token to do the login.
                                token: data.token,
    
                                // The Csrf Token
                                key: data.key,
    
                                // Firebase Key
                                original_key: data.original_key,
    
                                // The Final Redirect URL
                                redirect_url: data.redirect
    
                            });
    
                        },
    
                        /* Webhook Discord Creator Callback */
                        webhook: function (data, req, res) { return res.send(''); }
    
                    }
    
                },
    
            }
    
        }
    
    });
    
    // Website Function
    exports.example = functions.https.onRequest(app);

    Firebase Google oAuth

    This script was developed specifically to work with Google's Auth of Firebase.

    First you need to configure your JSON data and your custom method file if you want to add anything extra to happen during the login.

    JSON Data

    const JSONDATA = {
    
        // Vars Session
        varsSession: {
            firebase_token: "firebase_token",
            google_token: "google_token"
        },
    
        // URL
        url: {
            nativeLogin: "/firebase/nativeLogin.js",
            nativeLoginClient: "/firebase/nativeLoginClient.js",
            nativeLogout: "/firebase/nativeLogout.js",
            loginServer: "/firebase/loginServer",
            logoutServer: "/firebase/logoutServer",
            fireLogin: "/fireLogin"
        },
    
        // Login Redirect Meta
        redirectMetaPages: {
            
            // Basic Info
            login: "<script src=\"/file.js\"></script>",
            loginTitle: "Login...",
            firebaseVersion: "8.2.6",
    
            // Check Auth Time
            checkAuthTime: (decodedIdToken) => {
    
                // Only process if the user just signed in in the last 5 minutes.
                if (new Date().getTime() / 1000 - decodedIdToken.auth_time < 5 * 60) {
                    return true;
                }
    
                // Nope
                else { return false; }
    
            },
    
            // Cookie Time Generator
            cookieTimeGenerator: (decodedIdToken) => {
    
                // Set session expiration to 5 days.
                const expiresIn = 60 * 60 * 24 * 5 * 1000;
    
                // Complete
                return expiresIn;
    
            }
            
        }
    
    }
    
    // Start App
    const app = expressTemplate({
    
        ...
    
        // Insert the JSON Data here
        firebaseGoogle: JSONDATA
    
        ...
    
    });

    /file.js

    var customFirebaseLoginRedirect = {
    
        // Before Login
        beforeLogin: (provider, type, extra) => {
            // provider - firebase.auth.GoogleAuthProvider() value
            // type - event type 
            // extra - some extra value
            return;
        },
    
        // Before Logout
        beforeLogout: () => {
            return;
        },
    
        // Fail Login
        failLogout: () => {
            return;
        },
    
        // Error
        failLogout: (err, id) => {
            alert(err.message);
            return;
        }
    
    };

    /index.html (meta)

    Now you need to add META to your page.

    <script>firebase.initializeApp(firebaseCfg);</script>
    <script src="/firebase/nativeLoginClient.js"></script>
    <script src="/firebase/nativeLogout.js"></script>
    <script src="/file.js"></script>

    The file "nativeLoginClient.js" contains the method "updateFirebaseUserToken();". You can use this method to validate that your server token is valid. You can choose a custom method to run after the new token is updated. The default method is made to reload the page.

    var user_token_validated_in_the_server_side = false;
    firebase.auth().onAuthStateChanged(function (user) {
    
        // The Value is False. The new token will be added now.
        if(user && !user_token_validated_in_the_server_side) {
            updateFirebaseUserToken(user, (json) => {
    
                // Show Request Result
                console.log(json); 
                
                // Reload the page
                location.reload(); 
                
            });
        }
    
    });

    /index.html (body)

    Don't forget to add the login and logout buttons.

    <!-- Logout Button -->
    <a id="logout" href="javascript:void(0);">
        Logout
    </a>
    <script>$("#logout").click(function () { tinyLogoutFirebase(); });</script>
    
    <!-- Login Button -->
    <a href="/fireLogin?redirect=homepage"> <!-- This url will redirect to /homepage -->
        Login
    </a>

    Install

    npm i @tinypudding/firebase-express-template

    DownloadsWeekly Downloads

    80

    Version

    1.2.17

    License

    MIT

    Unpacked Size

    63.4 kB

    Total Files

    23

    Last publish

    Collaborators

    • jasmindreasond