cloud-run-gemini-chat/Application/CloudRun/Node-Express/app.js (105 lines of code) (raw):

var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); const https = require('https'); const session = require('cookie-session') const { doubleCsrf } = require("csrf-csrf"); const secrets = require('./secrets'); const gemini = require('./gemini'); // Page Routers var indexRouter = require('./routes/index'); var aboutRouter = require('./routes/about'); var geminiRouter = require('./routes/gemini'); const CSRF_SECRET = "super csrf secret"; const COOKIES_SECRET = "super cookie secret"; const CSRF_COOKIE_NAME = "x-csrf-token"; // This is referenced in app.js var api_key = null; var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser(COOKIES_SECRET)); app.use(express.static(path.join(__dirname, 'public'))); // app.use('/', indexRouter); app.use('/about', aboutRouter); app.use('/gemini', geminiRouter); app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: COOKIES_SECRET, resave: false, saveUninitialized: true, cookie: { secure: true } })) const { invalidCsrfTokenError, generateToken, doubleCsrfProtection } = doubleCsrf({ getSecret: () => CSRF_SECRET, cookieName: CSRF_COOKIE_NAME, cookieOptions: { sameSite: false, secure: false, signed: true }, // not ideal for production, development only }); // Error handling, validation error interception const csrfErrorHandler = (error, req, res, next) => { if (error == invalidCsrfTokenError) { res.status(403).json({ error: "csrf validation error", }); } else { next(); } }; // app.use(doubleCsrfProtection); app.get('/', async (req, res) => { const csrfToken = generateToken(req, res); res.render('index', {csrfToken: csrfToken}); }); app.post( '/ask', doubleCsrfProtection, csrfErrorHandler, async (req, res) => { if (!("text" in req.body)) { msg = "Error: Form validation failed."; res.setHeader('Content-type', 'application/json'); res.end(create_response(msg)); return; } const token = req.body.token; const model = req.body.model; const question = req.body.text; if (question.length == 0) { msg = "Please enter a question."; res.setHeader('Content-type', 'application/json'); res.end(create_response(msg)); return; } if (api_key == null) { api_key = await secrets.init_secrets(); } if (api_key == null) { msg = "Error: Secrets Manager access failed"; res.setHeader('Content-type', 'application/json'); res.end(create_response(msg)); return; } try { answer = await gemini.ask_gemini(api_key, model, question); } catch (error) { console.log(`Exception: ${error.message}`); answer = 'Error: request failed. Try again'; } res.setHeader('Content-type', 'application/json'); res.end(create_response(answer)); }) // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); function create_response(msg) { resp = { 'text': msg} return JSON.stringify(resp); } module.exports = app;