| require('dotenv').config(); |
| const path = require('path'); |
| require('module-alias')({ base: path.resolve(__dirname, '..') }); |
| const cors = require('cors'); |
| const axios = require('axios'); |
| const express = require('express'); |
| const passport = require('passport'); |
| const mongoSanitize = require('express-mongo-sanitize'); |
| const { jwtLogin, passportLogin } = require('~/strategies'); |
| const { connectDb, indexSync } = require('~/lib/db'); |
| const { isEnabled } = require('~/server/utils'); |
| const { ldapLogin } = require('~/strategies'); |
| const { logger } = require('~/config'); |
| const validateImageRequest = require('./middleware/validateImageRequest'); |
| const errorController = require('./controllers/ErrorController'); |
| const configureSocialLogins = require('./socialLogins'); |
| const AppService = require('./services/AppService'); |
| const noIndex = require('./middleware/noIndex'); |
| const routes = require('./routes'); |
|
|
| const { PORT, HOST, ALLOW_SOCIAL_LOGIN } = process.env ?? {}; |
|
|
| const port = Number(PORT) || 3080; |
| const host = HOST || 'localhost'; |
|
|
| const startServer = async () => { |
| if (typeof Bun !== 'undefined') { |
| axios.defaults.headers.common['Accept-Encoding'] = 'gzip'; |
| } |
| await connectDb(); |
| logger.info('Connected to MongoDB'); |
| await indexSync(); |
|
|
| const app = express(); |
| app.disable('x-powered-by'); |
| await AppService(app); |
|
|
| app.get('/health', (_req, res) => res.status(200).send('OK')); |
|
|
| |
| app.use(noIndex); |
| app.use(errorController); |
| app.use(express.json({ limit: '3mb' })); |
| app.use(mongoSanitize()); |
| app.use(express.urlencoded({ extended: true, limit: '3mb' })); |
| app.use(express.static(app.locals.paths.dist)); |
| app.use(express.static(app.locals.paths.fonts)); |
| app.use(express.static(app.locals.paths.assets)); |
| app.set('trust proxy', 1); |
| app.use(cors()); |
|
|
| if (!ALLOW_SOCIAL_LOGIN) { |
| console.warn( |
| 'Social logins are disabled. Set Environment Variable "ALLOW_SOCIAL_LOGIN" to true to enable them.', |
| ); |
| } |
|
|
| |
| app.use(passport.initialize()); |
| passport.use(await jwtLogin()); |
| passport.use(passportLogin()); |
|
|
| |
| if (process.env.LDAP_URL && process.env.LDAP_USER_SEARCH_BASE) { |
| passport.use(ldapLogin); |
| } |
|
|
| if (isEnabled(ALLOW_SOCIAL_LOGIN)) { |
| configureSocialLogins(app); |
| } |
|
|
| app.use('/oauth', routes.oauth); |
| |
| app.use('/api/auth', routes.auth); |
| app.use('/api/keys', routes.keys); |
| app.use('/api/user', routes.user); |
| app.use('/api/search', routes.search); |
| app.use('/api/ask', routes.ask); |
| app.use('/api/edit', routes.edit); |
| app.use('/api/messages', routes.messages); |
| app.use('/api/convos', routes.convos); |
| app.use('/api/presets', routes.presets); |
| app.use('/api/prompts', routes.prompts); |
| app.use('/api/categories', routes.categories); |
| app.use('/api/tokenizer', routes.tokenizer); |
| app.use('/api/endpoints', routes.endpoints); |
| app.use('/api/balance', routes.balance); |
| app.use('/api/models', routes.models); |
| app.use('/api/plugins', routes.plugins); |
| app.use('/api/config', routes.config); |
| app.use('/api/assistants', routes.assistants); |
| app.use('/api/files', await routes.files.initialize()); |
| app.use('/images/', validateImageRequest, routes.staticRoute); |
| app.use('/api/share', routes.share); |
| app.use('/api/roles', routes.roles); |
|
|
| app.use((req, res) => { |
| res.sendFile(path.join(app.locals.paths.dist, 'index.html')); |
| }); |
|
|
| app.listen(port, host, () => { |
| if (host == '0.0.0.0') { |
| logger.info( |
| `Server listening on all interfaces at port ${port}. Use http://localhost:${port} to access it`, |
| ); |
| } else { |
| logger.info(`Server listening at http://${host == '0.0.0.0' ? 'localhost' : host}:${port}`); |
| } |
| }); |
| }; |
|
|
| startServer(); |
|
|
| let messageCount = 0; |
| process.on('uncaughtException', (err) => { |
| if (!err.message.includes('fetch failed')) { |
| logger.error('There was an uncaught error:', err); |
| } |
|
|
| if (err.message.includes('fetch failed')) { |
| if (messageCount === 0) { |
| logger.warn('Meilisearch error, search will be disabled'); |
| messageCount++; |
| } |
|
|
| return; |
| } |
|
|
| if (err.message.includes('OpenAIError') || err.message.includes('ChatCompletionMessage')) { |
| logger.error( |
| '\n\nAn Uncaught `OpenAIError` error may be due to your reverse-proxy setup or stream configuration, or a bug in the `openai` node package.', |
| ); |
| return; |
| } |
|
|
| process.exit(1); |
| }); |
|
|