2015-07-20 00:09:47 -07:00
'use strict' ;
exports = module . exports = {
2021-05-01 11:21:09 -07:00
start ,
stop
2015-07-20 00:09:47 -07:00
} ;
2021-05-03 22:55:43 -07:00
const assert = require ( 'assert' ) ,
2015-07-20 00:09:47 -07:00
cloudron = require ( './cloudron.js' ) ,
2019-07-25 14:40:52 -07:00
constants = require ( './constants.js' ) ,
2015-07-20 00:09:47 -07:00
database = require ( './database.js' ) ,
2020-08-04 09:34:03 -07:00
debug = require ( 'debug' ) ( 'box:server' ) ,
2016-05-02 09:39:38 -07:00
eventlog = require ( './eventlog.js' ) ,
2015-07-20 00:09:47 -07:00
express = require ( 'express' ) ,
http = require ( 'http' ) ,
middleware = require ( './middleware' ) ,
2017-08-18 17:56:01 -07:00
routes = require ( './routes/index.js' ) ,
2021-09-07 09:57:49 -07:00
safe = require ( 'safetydance' ) ,
2019-07-26 10:49:29 -07:00
settings = require ( './settings.js' ) ,
2020-02-21 12:17:06 -08:00
users = require ( './users.js' ) ,
2021-09-07 09:57:49 -07:00
util = require ( 'util' ) ,
2017-08-18 17:56:01 -07:00
ws = require ( 'ws' ) ;
2015-07-20 00:09:47 -07:00
2020-11-09 20:34:48 -08:00
let gHttpServer = null ;
2015-07-20 00:09:47 -07:00
function initializeExpressSync ( ) {
2021-09-07 09:57:49 -07:00
const app = express ( ) ;
const httpServer = http . createServer ( app ) ;
2015-07-20 00:09:47 -07:00
2017-08-18 17:56:01 -07:00
const wsServer = new ws . Server ( { noServer : true } ) ; // in noServer mode, we have to handle 'upgrade' and call handleUpgrade
2017-08-15 20:00:52 +02:00
2022-03-01 11:28:34 -08:00
const QUERY _LIMIT = '2mb' , // max size for json and urlencoded queries (see also client_max_body_size in nginx)
2015-07-20 00:09:47 -07:00
FIELD _LIMIT = 2 * 1024 * 1024 ; // max fields that can appear in multipart
2021-09-07 09:57:49 -07:00
const REQUEST _TIMEOUT = 20000 ; // timeout for all requests (see also setTimeout on the httpServer)
2015-07-20 00:09:47 -07:00
2021-09-07 09:57:49 -07:00
const json = middleware . json ( { strict : true , limit : QUERY _LIMIT } ) , // application/json
2015-07-20 00:09:47 -07:00
urlencoded = middleware . urlencoded ( { extended : false , limit : QUERY _LIMIT } ) ; // application/x-www-form-urlencoded
2016-05-31 11:14:59 -07:00
app . set ( 'json spaces' , 2 ) ; // pretty json
2015-07-20 00:09:47 -07:00
2017-01-16 16:49:01 +01:00
// for rate limiting
app . enable ( 'trust proxy' ) ;
2017-04-10 14:17:26 +02:00
if ( process . env . BOX _ENV !== 'test' ) {
2019-11-22 11:40:36 +01:00
app . use ( middleware . morgan ( function ( tokens , req , res ) {
return [
'Box' ,
tokens . method ( req , res ) ,
2020-02-21 12:17:06 -08:00
tokens . url ( req , res ) . replace ( /(access_token=)[^&]+/ , '$1' + '<redacted>' ) ,
2019-11-22 11:40:36 +01:00
tokens . status ( req , res ) ,
2020-06-18 09:27:09 -07:00
res . errorBody ? res . errorBody . status : '' , // attached by connect-lastmile. can be missing when router errors like 404
res . errorBody ? res . errorBody . message : '' , // attached by connect-lastmile. can be missing when router errors like 404
2019-11-22 11:40:36 +01:00
tokens [ 'response-time' ] ( req , res ) , 'ms' , '-' ,
tokens . res ( req , res , 'content-length' )
] . join ( ' ' ) ;
} , {
2017-04-10 14:17:26 +02:00
immediate : false ,
// only log failed requests by default
skip : function ( req , res ) { return res . statusCode < 400 ; }
} ) ) ;
}
2015-07-20 00:09:47 -07:00
2021-09-07 09:57:49 -07:00
const router = new express . Router ( ) ;
2015-07-20 00:09:47 -07:00
router . del = router . delete ; // amend router.del for readability further on
app
2018-03-08 09:27:56 -08:00
// the timeout middleware will respond with a 503. the request itself cannot be 'aborted' and will continue
// search for req.clearTimeout in route handlers to see places where this timeout is reset
. use ( middleware . timeout ( REQUEST _TIMEOUT , { respond : true } ) )
2017-10-31 12:04:26 -07:00
. use ( urlencoded )
. use ( middleware . cors ( { origins : [ '*' ] , allowCredentials : false } ) )
. use ( router )
. use ( middleware . lastMile ( ) ) ;
2015-07-20 00:09:47 -07:00
2019-12-09 15:02:51 -08:00
// NOTE: routes that use multi-part have to be whitelisted in the reverse proxy
2021-09-07 09:57:49 -07:00
const FILE _SIZE _LIMIT = '256mb' , // max file size that can be uploaded (see also client_max_body_size in nginx)
2015-07-20 00:09:47 -07:00
FILE _TIMEOUT = 60 * 1000 ; // increased timeout for file uploads (1 min)
2021-09-07 09:57:49 -07:00
const multipart = middleware . multipart ( { maxFieldsSize : FIELD _LIMIT , limit : FILE _SIZE _LIMIT , timeout : FILE _TIMEOUT } ) ;
2015-07-20 00:09:47 -07:00
2022-09-24 21:27:43 +02:00
// authentication
2020-02-06 14:50:12 +01:00
const password = routes . accesscontrol . passwordAuth ;
const token = routes . accesscontrol . tokenAuth ;
2022-09-24 21:27:43 +02:00
// authorization
2020-03-15 11:32:18 -07:00
const authorizeOwner = routes . accesscontrol . authorize ( users . ROLE _OWNER ) ;
2020-02-21 12:17:06 -08:00
const authorizeAdmin = routes . accesscontrol . authorize ( users . ROLE _ADMIN ) ;
2021-09-21 10:11:27 -07:00
const authorizeOperator = routes . accesscontrol . authorizeOperator ;
2020-02-21 12:17:06 -08:00
const authorizeUserManager = routes . accesscontrol . authorize ( users . ROLE _USER _MANAGER ) ;
2021-12-01 09:27:24 -08:00
const authorizeMailManager = routes . accesscontrol . authorize ( users . ROLE _MAIL _MANAGER ) ;
2022-09-24 21:27:43 +02:00
const authorizeUser = routes . accesscontrol . authorize ( users . ROLE _USER ) ;
2015-07-20 00:09:47 -07:00
// public routes
2020-12-21 22:36:10 -08:00
router . post ( '/api/v1/cloudron/setup' , json , routes . provision . setupTokenAuth , routes . provision . providerTokenAuth , routes . provision . setup ) ; // only available until no-domain
router . post ( '/api/v1/cloudron/restore' , json , routes . provision . setupTokenAuth , routes . provision . restore ) ; // only available until activated
router . post ( '/api/v1/cloudron/activate' , json , routes . provision . setupTokenAuth , routes . provision . activate ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/cloudron/status' , routes . provision . getStatus ) ;
2020-11-18 00:10:06 +01:00
router . get ( '/api/v1/cloudron/languages' , routes . cloudron . getLanguages ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/cloudron/avatar' , routes . branding . getCloudronAvatar ) ; // this is a public alias for /api/v1/branding/cloudron_avatar
2015-07-20 00:09:47 -07:00
2020-02-04 14:35:25 +01:00
// login/logout routes
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/cloudron/login' , json , password , routes . cloudron . login ) ;
2021-01-06 21:57:23 -08:00
router . get ( '/api/v1/cloudron/logout' , token , routes . cloudron . logout ) ; // this will invalidate the token if any and redirect to /login.html always
router . post ( '/api/v1/cloudron/password_reset_request' , json , routes . cloudron . passwordResetRequest ) ;
router . post ( '/api/v1/cloudron/password_reset' , json , routes . cloudron . passwordReset ) ;
router . post ( '/api/v1/cloudron/setup_account' , json , routes . cloudron . setupAccount ) ;
2020-02-04 14:35:25 +01:00
2016-06-02 15:58:58 -07:00
// cloudron routes
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/cloudron/update' , token , authorizeAdmin , routes . cloudron . getUpdateInfo ) ;
router . post ( '/api/v1/cloudron/update' , json , token , authorizeAdmin , routes . cloudron . update ) ;
router . post ( '/api/v1/cloudron/prepare_dashboard_domain' , json , token , authorizeAdmin , routes . cloudron . prepareDashboardDomain ) ;
2020-08-15 22:53:05 -07:00
router . post ( '/api/v1/cloudron/set_dashboard_domain' , json , token , authorizeAdmin , routes . cloudron . updateDashboardDomain ) ;
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/cloudron/renew_certs' , json , token , authorizeAdmin , routes . cloudron . renewCerts ) ;
2021-02-24 18:42:39 -08:00
router . post ( '/api/v1/cloudron/sync_dns' , json , token , authorizeAdmin , routes . cloudron . syncDnsRecords ) ;
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/cloudron/check_for_updates' , json , token , authorizeAdmin , routes . cloudron . checkForUpdates ) ;
router . get ( '/api/v1/cloudron/reboot' , token , authorizeAdmin , routes . cloudron . isRebootRequired ) ;
router . post ( '/api/v1/cloudron/reboot' , json , token , authorizeAdmin , routes . cloudron . reboot ) ;
2022-09-15 11:28:41 +02:00
router . get ( '/api/v1/cloudron/graphs' , token , authorizeAdmin , routes . graphs . getSystemGraphs ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/cloudron/disks' , token , authorizeAdmin , routes . cloudron . getDisks ) ;
router . get ( '/api/v1/cloudron/memory' , token , authorizeAdmin , routes . cloudron . getMemory ) ;
router . get ( '/api/v1/cloudron/logs/:unit' , token , authorizeAdmin , routes . cloudron . getLogs ) ;
router . get ( '/api/v1/cloudron/logstream/:unit' , token , authorizeAdmin , routes . cloudron . getLogStream ) ;
router . get ( '/api/v1/cloudron/eventlog' , token , authorizeAdmin , routes . eventlog . list ) ;
router . get ( '/api/v1/cloudron/eventlog/:eventId' , token , authorizeAdmin , routes . eventlog . get ) ;
router . post ( '/api/v1/cloudron/sync_external_ldap' , json , token , authorizeAdmin , routes . cloudron . syncExternalLdap ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/cloudron/server_ipv4' , token , authorizeAdmin , routes . cloudron . getServerIpv4 ) ;
router . get ( '/api/v1/cloudron/server_ipv6' , token , authorizeAdmin , routes . cloudron . getServerIpv6 ) ;
2020-07-10 14:10:52 +02:00
// task routes
router . get ( '/api/v1/tasks' , token , authorizeAdmin , routes . tasks . list ) ;
router . get ( '/api/v1/tasks/:taskId' , token , authorizeAdmin , routes . tasks . get ) ;
router . get ( '/api/v1/tasks/:taskId/logs' , token , authorizeAdmin , routes . tasks . getLogs ) ;
router . get ( '/api/v1/tasks/:taskId/logstream' , token , authorizeAdmin , routes . tasks . getLogStream ) ;
router . post ( '/api/v1/tasks/:taskId/stop' , json , token , authorizeAdmin , routes . tasks . stopTask ) ;
2021-04-21 12:00:07 -07:00
// notification routes (these are server level)
2021-05-28 14:34:18 -07:00
router . get ( '/api/v1/notifications' , token , authorizeAdmin , routes . notifications . list ) ;
router . get ( '/api/v1/notifications/:notificationId' , token , authorizeAdmin , routes . notifications . load , routes . notifications . get ) ;
router . post ( '/api/v1/notifications/:notificationId' , json , token , authorizeAdmin , routes . notifications . load , routes . notifications . update ) ;
2020-07-10 14:10:52 +02:00
// backup routes
2022-04-02 17:09:08 -07:00
router . get ( '/api/v1/backups' , token , authorizeAdmin , routes . backups . list ) ;
2022-04-03 08:29:59 -07:00
router . post ( '/api/v1/backups/create' , token , authorizeAdmin , routes . backups . create ) ;
2022-04-02 17:09:08 -07:00
router . post ( '/api/v1/backups/cleanup' , json , token , authorizeAdmin , routes . backups . cleanup ) ;
router . post ( '/api/v1/backups/remount' , json , token , authorizeAdmin , routes . backups . remount ) ;
router . post ( '/api/v1/backups/:backupId' , json , token , authorizeAdmin , routes . backups . update ) ;
2018-11-19 14:40:32 -08:00
2020-07-09 17:18:06 -07:00
// config route (for dashboard). can return some private configuration unlike status
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/config' , token , authorizeUser , routes . cloudron . getConfig ) ;
2018-06-28 17:40:57 -07:00
2018-04-26 19:57:44 -07:00
// working off the user behind the provided token
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/profile' , token , authorizeUser , routes . profile . get ) ;
router . post ( '/api/v1/profile' , json , token , authorizeUser , routes . profile . authorize , routes . profile . update ) ;
router . get ( '/api/v1/profile/avatar/:identifier' , routes . profile . getAvatar ) ; // this is not scoped so it can used directly in img tag
router . post ( '/api/v1/profile/avatar' , json , token , authorizeUser , ( req , res , next ) => { return typeof req . body . avatar === 'string' ? next ( ) : multipart ( req , res , next ) ; } , routes . profile . setAvatar ) ; // avatar is not exposed in LDAP. so it's personal and not locked
router . get ( '/api/v1/profile/backgroundImage' , token , authorizeUser , routes . profile . getBackgroundImage ) ;
router . post ( '/api/v1/profile/backgroundImage' , token , authorizeUser , multipart , routes . profile . setBackgroundImage ) ; // backgroundImage is not exposed in LDAP. so it's personal and not locked
router . post ( '/api/v1/profile/password' , json , token , authorizeUser , routes . users . verifyPassword , routes . profile . setPassword ) ;
router . post ( '/api/v1/profile/twofactorauthentication_secret' , json , token , authorizeUser , routes . profile . setTwoFactorAuthenticationSecret ) ;
router . post ( '/api/v1/profile/twofactorauthentication_enable' , json , token , authorizeUser , routes . profile . enableTwoFactorAuthentication ) ;
router . post ( '/api/v1/profile/twofactorauthentication_disable' , json , token , authorizeUser , routes . users . verifyPassword , routes . profile . disableTwoFactorAuthentication ) ;
2020-07-10 14:10:52 +02:00
// app password routes
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/app_passwords' , token , authorizeUser , routes . appPasswords . list ) ;
router . post ( '/api/v1/app_passwords' , json , token , authorizeUser , routes . appPasswords . add ) ;
router . get ( '/api/v1/app_passwords/:id' , token , authorizeUser , routes . appPasswords . get ) ;
router . del ( '/api/v1/app_passwords/:id' , token , authorizeUser , routes . appPasswords . del ) ;
2020-01-31 15:28:42 -08:00
2022-09-24 20:56:43 +02:00
// access tokens
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/tokens' , token , authorizeUser , routes . tokens . list ) ;
router . post ( '/api/v1/tokens' , json , token , authorizeUser , routes . tokens . add ) ;
router . get ( '/api/v1/tokens/:id' , token , authorizeUser , routes . tokens . verifyOwnership , routes . tokens . get ) ;
router . del ( '/api/v1/tokens/:id' , token , authorizeUser , routes . tokens . verifyOwnership , routes . tokens . del ) ;
2020-02-07 16:20:05 +01:00
2016-06-02 00:20:33 -07:00
// user routes
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/users' , token , authorizeUserManager , routes . users . list ) ;
2021-07-15 09:50:11 -07:00
router . post ( '/api/v1/users' , json , token , authorizeUserManager , routes . users . add ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/users/:userId' , token , authorizeUserManager , routes . users . load , routes . users . get ) ; // this is manage scope because it returns non-restricted fields
2021-06-26 09:57:07 -07:00
router . del ( '/api/v1/users/:userId' , token , authorizeUserManager , routes . users . load , routes . users . del ) ;
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/users/:userId' , json , token , authorizeUserManager , routes . users . load , routes . users . update ) ;
2021-07-15 09:50:11 -07:00
router . post ( '/api/v1/users/:userId/password' , json , token , authorizeUserManager , routes . users . load , routes . users . setPassword ) ;
2021-09-17 12:52:41 +02:00
router . post ( '/api/v1/users/:userId/ghost' , json , token , authorizeAdmin , routes . users . load , routes . users . setGhost ) ;
2020-07-10 14:10:52 +02:00
router . put ( '/api/v1/users/:userId/groups' , json , token , authorizeUserManager , routes . users . load , routes . users . setGroups ) ;
2022-04-24 22:11:27 +02:00
router . post ( '/api/v1/users/:userId/make_local' , json , token , authorizeUserManager , routes . users . load , routes . users . makeLocal ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/users/:userId/password_reset_link' , json , token , authorizeUserManager , routes . users . load , routes . users . getPasswordResetLink ) ;
router . post ( '/api/v1/users/:userId/send_password_reset_email' , json , token , authorizeUserManager , routes . users . load , routes . users . sendPasswordResetEmail ) ;
router . get ( '/api/v1/users/:userId/invite_link' , json , token , authorizeUserManager , routes . users . load , routes . users . getInviteLink ) ;
router . post ( '/api/v1/users/:userId/send_invite_email' , json , token , authorizeUserManager , routes . users . load , routes . users . sendInviteEmail ) ;
router . post ( '/api/v1/users/:userId/twofactorauthentication_disable' , json , token , authorizeUserManager , routes . users . load , routes . users . disableTwoFactorAuthentication ) ;
2015-07-20 00:09:47 -07:00
2016-02-09 13:34:01 -08:00
// Group management
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/groups' , token , authorizeUserManager , routes . groups . list ) ;
2021-06-28 15:15:28 -07:00
router . post ( '/api/v1/groups' , json , token , authorizeUserManager , routes . groups . add ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/groups/:groupId' , token , authorizeUserManager , routes . groups . get ) ;
2022-06-22 17:36:19 -07:00
router . put ( '/api/v1/groups/:groupId/members' , json , token , authorizeUserManager , routes . groups . setMembers ) ;
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/groups/:groupId' , json , token , authorizeUserManager , routes . groups . update ) ;
router . del ( '/api/v1/groups/:groupId' , token , authorizeUserManager , routes . groups . remove ) ;
2016-02-09 13:34:01 -08:00
2019-05-05 13:00:45 -07:00
// appstore and subscription routes
2022-03-31 22:04:52 -07:00
router . post ( '/api/v1/appstore/register_cloudron' , json , token , authorizeOwner , routes . appstore . registerCloudron ) ;
router . get ( '/api/v1/appstore/web_token' , json , token , authorizeOwner , routes . appstore . getWebToken ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/appstore/subscription' , token , authorizeUser , routes . appstore . getSubscription ) ; // for all users
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/appstore/apps' , token , authorizeAdmin , routes . appstore . getApps ) ;
router . get ( '/api/v1/appstore/apps/:appstoreId' , token , authorizeAdmin , routes . appstore . getApp ) ;
router . get ( '/api/v1/appstore/apps/:appstoreId/versions/:versionId' , token , authorizeAdmin , routes . appstore . getAppVersion ) ;
2019-05-04 11:45:03 -07:00
2015-07-20 00:09:47 -07:00
// app routes
2022-09-24 21:27:43 +02:00
router . post ( '/api/v1/apps/install' , json , token , authorizeAdmin , routes . apps . install ) ;
router . get ( '/api/v1/apps' , token , authorizeUser , routes . apps . listByUser ) ;
2021-09-21 17:28:58 -07:00
router . get ( '/api/v1/apps/:id' , token , routes . apps . load , authorizeOperator , routes . apps . getApp ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/apps/:id/icon' , token , routes . apps . load , authorizeUser , routes . apps . getAppIcon ) ;
router . post ( '/api/v1/apps/:id/uninstall' , json , token , routes . apps . load , authorizeAdmin , routes . apps . uninstall ) ;
router . post ( '/api/v1/apps/:id/configure/access_restriction' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setAccessRestriction ) ;
router . post ( '/api/v1/apps/:id/configure/operators' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setOperators ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/configure/label' , json , token , routes . apps . load , authorizeOperator , routes . apps . setLabel ) ;
router . post ( '/api/v1/apps/:id/configure/tags' , json , token , routes . apps . load , authorizeOperator , routes . apps . setTags ) ;
router . post ( '/api/v1/apps/:id/configure/icon' , json , token , routes . apps . load , authorizeOperator , routes . apps . setIcon ) ;
router . post ( '/api/v1/apps/:id/configure/memory_limit' , json , token , routes . apps . load , authorizeOperator , routes . apps . setMemoryLimit ) ;
router . post ( '/api/v1/apps/:id/configure/cpu_shares' , json , token , routes . apps . load , authorizeOperator , routes . apps . setCpuShares ) ;
router . post ( '/api/v1/apps/:id/configure/automatic_backup' , json , token , routes . apps . load , authorizeOperator , routes . apps . setAutomaticBackup ) ;
router . post ( '/api/v1/apps/:id/configure/automatic_update' , json , token , routes . apps . load , authorizeOperator , routes . apps . setAutomaticUpdate ) ;
router . post ( '/api/v1/apps/:id/configure/reverse_proxy' , json , token , routes . apps . load , authorizeOperator , routes . apps . setReverseProxyConfig ) ;
router . post ( '/api/v1/apps/:id/configure/cert' , json , token , routes . apps . load , authorizeOperator , routes . apps . setCertificate ) ;
router . post ( '/api/v1/apps/:id/configure/debug_mode' , json , token , routes . apps . load , authorizeOperator , routes . apps . setDebugMode ) ;
2021-09-22 12:45:11 -07:00
router . post ( '/api/v1/apps/:id/configure/mailbox' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setMailbox ) ;
2021-10-01 12:09:13 -07:00
router . post ( '/api/v1/apps/:id/configure/inbox' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setInbox ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/configure/env' , json , token , routes . apps . load , authorizeOperator , routes . apps . setEnvironment ) ;
2022-06-01 22:44:52 -07:00
router . post ( '/api/v1/apps/:id/configure/storage' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setStorage ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/configure/location' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setLocation ) ;
router . post ( '/api/v1/apps/:id/configure/mounts' , json , token , routes . apps . load , authorizeAdmin , routes . apps . setMounts ) ;
2021-09-27 21:41:41 -07:00
router . post ( '/api/v1/apps/:id/configure/crontab' , json , token , routes . apps . load , authorizeOperator , routes . apps . setCrontab ) ;
2022-06-08 11:21:09 +02:00
router . post ( '/api/v1/apps/:id/configure/upstream_uri' , json , token , routes . apps . load , authorizeOperator , routes . apps . setUpstreamUri ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/repair' , json , token , routes . apps . load , authorizeOperator , routes . apps . repair ) ;
2021-09-21 19:53:05 -07:00
router . post ( '/api/v1/apps/:id/check_for_updates' , json , token , routes . apps . load , authorizeOperator , routes . apps . checkForUpdates ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/update' , json , token , routes . apps . load , authorizeOperator , routes . apps . update ) ;
router . post ( '/api/v1/apps/:id/restore' , json , token , routes . apps . load , authorizeOperator , routes . apps . restore ) ;
router . post ( '/api/v1/apps/:id/import' , json , token , routes . apps . load , authorizeOperator , routes . apps . importApp ) ;
router . post ( '/api/v1/apps/:id/export' , json , token , routes . apps . load , authorizeOperator , routes . apps . exportApp ) ;
router . post ( '/api/v1/apps/:id/backup' , json , token , routes . apps . load , authorizeOperator , routes . apps . backup ) ;
router . get ( '/api/v1/apps/:id/backups' , token , routes . apps . load , authorizeOperator , routes . apps . listBackups ) ;
2022-04-02 17:09:08 -07:00
router . post ( '/api/v1/apps/:id/backups/:backupId' , json , token , routes . apps . load , authorizeOperator , routes . apps . updateBackup ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/start' , json , token , routes . apps . load , authorizeOperator , routes . apps . start ) ;
router . post ( '/api/v1/apps/:id/stop' , json , token , routes . apps . load , authorizeOperator , routes . apps . stop ) ;
router . post ( '/api/v1/apps/:id/restart' , json , token , routes . apps . load , authorizeOperator , routes . apps . restart ) ;
router . get ( '/api/v1/apps/:id/logstream' , token , routes . apps . load , authorizeOperator , routes . apps . getLogStream ) ;
router . get ( '/api/v1/apps/:id/logs' , token , routes . apps . load , authorizeOperator , routes . apps . getLogs ) ;
2021-09-21 19:45:29 -07:00
router . get ( '/api/v1/apps/:id/eventlog' , token , routes . apps . load , authorizeOperator , routes . apps . listEventlog ) ;
2021-09-21 22:29:19 -07:00
router . get ( '/api/v1/apps/:id/limits' , token , routes . apps . load , authorizeOperator , routes . apps . getLimits ) ;
2021-09-21 22:19:20 -07:00
router . get ( '/api/v1/apps/:id/task' , token , routes . apps . load , authorizeOperator , routes . apps . getTask ) ;
2022-09-14 13:03:14 +02:00
router . get ( '/api/v1/apps/:id/graphs' , token , routes . apps . load , authorizeOperator , routes . graphs . getAppGraphs ) ;
2021-09-21 10:11:27 -07:00
router . post ( '/api/v1/apps/:id/clone' , json , token , routes . apps . load , authorizeAdmin , routes . apps . clone ) ;
router . get ( '/api/v1/apps/:id/download' , token , routes . apps . load , authorizeOperator , routes . apps . downloadFile ) ;
router . post ( '/api/v1/apps/:id/upload' , json , token , multipart , routes . apps . load , authorizeOperator , routes . apps . uploadFile ) ;
2021-09-25 17:19:58 -07:00
router . use ( '/api/v1/apps/:id/files/*' , token , routes . apps . load , authorizeOperator , routes . filemanager . proxy ( 'app' ) ) ;
2022-05-16 10:26:30 -07:00
router . post ( '/api/v1/apps/:id/exec' , json , token , routes . apps . load , authorizeOperator , routes . apps . createExec ) ;
router . get ( '/api/v1/apps/:id/exec/:execId/start' , token , routes . apps . load , authorizeOperator , routes . apps . startExec ) ;
router . get ( '/api/v1/apps/:id/exec/:execId' , token , routes . apps . load , authorizeOperator , routes . apps . getExec ) ;
2020-12-22 17:19:26 -08:00
2017-08-18 17:56:01 -07:00
// websocket cannot do bearer authentication
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/apps/:id/exec/:execId/startws' , token , routes . apps . load , authorizeOperator , routes . apps . startExecWebSocket ) ;
2015-07-20 00:09:47 -07:00
2022-07-06 19:15:59 +02:00
// app links in dashboard
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/applinks' , token , authorizeUser , routes . applinks . listByUser ) ;
2022-07-07 13:01:23 +02:00
router . post ( '/api/v1/applinks' , json , token , authorizeAdmin , routes . applinks . add ) ;
router . get ( '/api/v1/applinks/:id' , token , authorizeAdmin , routes . applinks . get ) ;
router . post ( '/api/v1/applinks/:id' , json , token , authorizeAdmin , routes . applinks . update ) ;
router . del ( '/api/v1/applinks/:id' , token , authorizeAdmin , routes . applinks . remove ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/applinks/:id/icon' , token , authorizeUser , routes . applinks . getIcon ) ;
2022-07-06 19:15:59 +02:00
2020-07-10 14:10:52 +02:00
// branding routes
router . get ( '/api/v1/branding/:setting' , token , authorizeOwner , routes . branding . get ) ;
router . post ( '/api/v1/branding/:setting' , json , token , authorizeOwner , ( req , res , next ) => {
2020-03-15 11:32:18 -07:00
return req . params . setting === 'cloudron_avatar' ? multipart ( req , res , next ) : next ( ) ;
2020-03-15 16:38:15 -07:00
} , routes . branding . set ) ;
2020-03-15 11:32:18 -07:00
2020-08-31 18:22:33 -07:00
// network routes
2020-08-31 22:53:22 -07:00
router . get ( '/api/v1/network/blocklist' , token , authorizeOwner , routes . network . getBlocklist ) ;
router . post ( '/api/v1/network/blocklist' , json , token , authorizeOwner , routes . network . setBlocklist ) ;
2020-08-31 18:22:33 -07:00
2016-05-06 08:42:27 -07:00
// settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above)
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/settings/:setting' , token , authorizeAdmin , routes . settings . get ) ;
router . post ( '/api/v1/settings/backup_config' , json , token , authorizeOwner , routes . settings . setBackupConfig ) ;
router . post ( '/api/v1/settings/:setting' , json , token , authorizeAdmin , routes . settings . set ) ;
2018-10-12 17:04:04 -07:00
2017-06-28 17:06:12 -05:00
// email routes
2020-08-20 23:05:52 -07:00
router . get ( '/api/v1/mailserver/eventlog' , token , authorizeOwner , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/clear_eventlog' , token , authorizeOwner , routes . mailserver . proxy ) ;
2021-12-01 09:27:24 -08:00
router . use ( '/api/v1/mailserver/files/*' , token , authorizeOwner , routes . filemanager . proxy ( 'mail' ) ) ;
2020-08-20 23:05:52 -07:00
router . get ( '/api/v1/mailserver/location' , token , authorizeAdmin , routes . mailserver . getLocation ) ;
router . post ( '/api/v1/mailserver/location' , json , token , authorizeAdmin , routes . mailserver . setLocation ) ;
router . get ( '/api/v1/mailserver/max_email_size' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/max_email_size' , token , authorizeAdmin , routes . mailserver . proxy ) ;
2020-08-22 10:22:57 -07:00
router . get ( '/api/v1/mailserver/spam_acl' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/spam_acl' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . get ( '/api/v1/mailserver/spam_custom_config' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/spam_custom_config' , token , authorizeAdmin , routes . mailserver . proxy ) ;
2021-10-13 14:01:07 -07:00
router . get ( '/api/v1/mailserver/dnsbl_config' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/dnsbl_config' , token , authorizeAdmin , routes . mailserver . proxy ) ;
2020-11-19 17:10:45 -08:00
router . get ( '/api/v1/mailserver/solr_config' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/solr_config' , token , authorizeAdmin , routes . mailserver . proxy , routes . mailserver . restart ) ;
2021-12-08 10:20:43 -08:00
router . get ( '/api/v1/mailserver/mailbox_sharing' , token , authorizeAdmin , routes . mailserver . proxy ) ;
router . post ( '/api/v1/mailserver/mailbox_sharing' , token , authorizeAdmin , routes . mailserver . proxy , routes . mailserver . restart ) ;
2021-12-01 09:27:24 -08:00
router . get ( '/api/v1/mailserver/usage' , token , authorizeMailManager , routes . mailserver . proxy ) ;
2022-09-20 19:20:52 +02:00
2022-09-22 19:30:05 +02:00
router . use ( '/api/v1/mailserver/queue' , token , authorizeAdmin , routes . mailserver . queueProxy ) ;
2020-02-07 14:11:52 -08:00
2021-12-01 09:27:24 -08:00
router . get ( '/api/v1/mail/:domain' , token , authorizeMailManager , routes . mail . getDomain ) ;
router . post ( '/api/v1/mail/:domain/enable' , json , token , authorizeAdmin , routes . mail . setMailEnabled ) ;
router . get ( '/api/v1/mail/:domain/status' , token , authorizeMailManager , routes . mail . getStatus ) ;
2021-12-02 14:56:35 -08:00
router . post ( '/api/v1/mail/:domain/mail_from_validation' , json , token , authorizeMailManager , routes . mail . setMailFromValidation ) ;
2021-12-01 09:27:24 -08:00
router . post ( '/api/v1/mail/:domain/catch_all' , json , token , authorizeMailManager , routes . mail . setCatchAllAddress ) ;
2020-07-10 14:10:52 +02:00
router . post ( '/api/v1/mail/:domain/relay' , json , token , authorizeAdmin , routes . mail . setMailRelay ) ;
2021-12-01 09:27:24 -08:00
router . post ( '/api/v1/mail/:domain/banner' , json , token , authorizeMailManager , routes . mail . setBanner ) ;
router . post ( '/api/v1/mail/:domain/send_test_mail' , json , token , authorizeMailManager , routes . mail . sendTestMail ) ;
router . get ( '/api/v1/mail/:domain/mailbox_count' , token , authorizeMailManager , routes . mail . getMailboxCount ) ;
router . get ( '/api/v1/mail/:domain/mailboxes' , token , authorizeMailManager , routes . mail . listMailboxes ) ;
router . get ( '/api/v1/mail/:domain/mailboxes/:name' , token , authorizeMailManager , routes . mail . getMailbox ) ;
router . post ( '/api/v1/mail/:domain/mailboxes' , json , token , authorizeMailManager , routes . mail . addMailbox ) ;
router . post ( '/api/v1/mail/:domain/mailboxes/:name' , json , token , authorizeMailManager , routes . mail . updateMailbox ) ;
router . del ( '/api/v1/mail/:domain/mailboxes/:name' , json , token , authorizeMailManager , routes . mail . delMailbox ) ;
router . get ( '/api/v1/mail/:domain/mailboxes/:name/aliases' , token , authorizeMailManager , routes . mail . getAliases ) ;
router . put ( '/api/v1/mail/:domain/mailboxes/:name/aliases' , json , token , authorizeMailManager , routes . mail . setAliases ) ;
router . get ( '/api/v1/mail/:domain/lists' , token , authorizeMailManager , routes . mail . getLists ) ;
router . post ( '/api/v1/mail/:domain/lists' , json , token , authorizeMailManager , routes . mail . addList ) ;
router . get ( '/api/v1/mail/:domain/lists/:name' , token , authorizeMailManager , routes . mail . getList ) ;
router . post ( '/api/v1/mail/:domain/lists/:name' , json , token , authorizeMailManager , routes . mail . updateList ) ;
router . del ( '/api/v1/mail/:domain/lists/:name' , token , authorizeMailManager , routes . mail . delList ) ;
2020-07-10 14:10:52 +02:00
// support routes
router . post ( '/api/v1/support/ticket' , json , token , authorizeAdmin , routes . support . canCreateTicket , routes . support . createTicket ) ;
router . get ( '/api/v1/support/remote_support' , token , authorizeAdmin , routes . support . getRemoteSupport ) ;
router . post ( '/api/v1/support/remote_support' , json , token , authorizeAdmin , routes . support . canEnableRemoteSupport , routes . support . enableRemoteSupport ) ;
2017-04-18 14:49:28 -07:00
2017-10-28 22:18:07 +02:00
// domain routes
2020-12-23 15:34:23 -08:00
router . post ( '/api/v1/domains' , json , token , authorizeAdmin , routes . domains . add ) ;
2022-09-24 21:27:43 +02:00
router . get ( '/api/v1/domains' , token , authorizeUser , routes . domains . list ) ;
2020-12-23 15:34:23 -08:00
router . get ( '/api/v1/domains/:domain' , token , authorizeAdmin , routes . domains . get ) ; // this is manage scope because it returns non-restricted fields
2022-09-24 21:27:43 +02:00
router . post ( '/api/v1/domains/:domain/config' , json , token , authorizeAdmin , routes . domains . setConfig ) ;
router . post ( '/api/v1/domains/:domain/wellknown' , json , token , authorizeAdmin , routes . domains . setWellKnown ) ;
2020-12-23 15:34:23 -08:00
router . del ( '/api/v1/domains/:domain' , token , authorizeAdmin , routes . domains . del ) ;
router . get ( '/api/v1/domains/:domain/dns_check' , token , authorizeAdmin , routes . domains . checkDnsRecords ) ;
2017-10-28 22:18:07 +02:00
2020-10-27 22:39:05 -07:00
// volume routes
2020-10-30 10:16:52 -07:00
router . post ( '/api/v1/volumes' , json , token , authorizeAdmin , routes . volumes . add ) ;
router . get ( '/api/v1/volumes' , token , authorizeAdmin , routes . volumes . list ) ;
router . get ( '/api/v1/volumes/:id' , token , authorizeAdmin , routes . volumes . load , routes . volumes . get ) ;
router . del ( '/api/v1/volumes/:id' , token , authorizeAdmin , routes . volumes . load , routes . volumes . del ) ;
2021-05-13 15:33:16 -07:00
router . get ( '/api/v1/volumes/:id/status' , token , authorizeAdmin , routes . volumes . load , routes . volumes . getStatus ) ;
2021-10-11 15:51:16 +02:00
router . post ( '/api/v1/volumes/:id/remount' , token , authorizeAdmin , routes . volumes . load , routes . volumes . remount ) ;
2021-09-25 17:19:58 -07:00
router . use ( '/api/v1/volumes/:id/files/*' , token , authorizeAdmin , routes . filemanager . proxy ( 'volume' ) ) ;
2020-10-27 22:39:05 -07:00
2021-01-19 18:36:28 -08:00
// service routes
2021-09-20 09:15:28 -07:00
router . get ( '/api/v1/services' , token , authorizeAdmin , routes . services . list ) ;
2020-07-10 14:10:52 +02:00
router . get ( '/api/v1/services/:service' , token , authorizeAdmin , routes . services . get ) ;
router . post ( '/api/v1/services/:service' , json , token , authorizeAdmin , routes . services . configure ) ;
router . get ( '/api/v1/services/:service/logs' , token , authorizeAdmin , routes . services . getLogs ) ;
router . get ( '/api/v1/services/:service/logstream' , token , authorizeAdmin , routes . services . getLogStream ) ;
router . post ( '/api/v1/services/:service/restart' , json , token , authorizeAdmin , routes . services . restart ) ;
2021-01-21 12:53:38 -08:00
router . post ( '/api/v1/services/:service/rebuild' , json , token , authorizeAdmin , routes . services . rebuild ) ;
2018-11-15 19:59:08 +01:00
2020-12-22 17:19:26 -08:00
// well known
router . get ( '/well-known-handler/*' , routes . wellknown . get ) ;
2016-06-01 16:31:47 -07:00
// disable server socket "idle" timeout. we use the timeout middleware to handle timeouts on a route level
2016-06-01 17:33:04 -07:00
// we rely on nginx for timeouts on the TCP level (see client_header_timeout)
2016-01-18 12:20:09 -08:00
httpServer . setTimeout ( 0 ) ;
2015-07-20 00:09:47 -07:00
// upgrade handler
2017-08-17 09:32:38 +02:00
httpServer . on ( 'upgrade' , function ( req , socket , head ) {
2017-08-18 17:56:01 -07:00
// create a node response object for express
2022-04-14 17:41:41 -05:00
const res = new http . ServerResponse ( { } ) ;
2017-08-18 17:56:01 -07:00
res . assignSocket ( socket ) ;
2017-08-17 11:56:51 +02:00
if ( req . headers . upgrade === 'websocket' ) {
2017-08-18 17:56:01 -07:00
res . handleUpgrade = function ( callback ) {
wsServer . handleUpgrade ( req , socket , head , callback ) ;
} ;
2017-08-17 11:56:51 +02:00
} else {
res . sendUpgradeHandshake = function ( ) { // could extend express.response as well
socket . write ( 'HTTP/1.1 101 TCP Handshake\r\n' +
'Upgrade: tcp\r\n' +
'Connection: Upgrade\r\n' +
'\r\n' ) ;
} ;
}
2017-08-18 17:56:01 -07:00
// route through express middleware. if we provide no callback, express will provide a 'finalhandler'
// TODO: it's not clear if socket needs to be destroyed
app ( req , res ) ;
2017-08-17 09:32:38 +02:00
} ) ;
2015-07-20 00:09:47 -07:00
return httpServer ;
}
2021-09-07 09:57:49 -07:00
async function start ( ) {
2015-07-20 00:09:47 -07:00
assert . strictEqual ( gHttpServer , null , 'Server is already up and running.' ) ;
2020-08-04 09:34:03 -07:00
debug ( '==========================================' ) ;
debug ( ` Cloudron ${ constants . VERSION } ` ) ;
debug ( '==========================================' ) ;
2015-07-20 00:09:47 -07:00
gHttpServer = initializeExpressSync ( ) ;
2021-09-07 09:57:49 -07:00
await database . initialize ( ) ;
await settings . initCache ( ) ; // pre-load very often used settings
await cloudron . initialize ( ) ;
await util . promisify ( gHttpServer . listen . bind ( gHttpServer ) ) ( constants . PORT , '127.0.0.1' ) ;
await safe ( eventlog . add ( eventlog . ACTION _START , { userId : null , username : 'boot' } , { version : constants . VERSION } ) ) ; // can fail if db down
2015-07-20 00:09:47 -07:00
}
2021-09-07 09:57:49 -07:00
async function stop ( ) {
if ( ! gHttpServer ) return ;
2015-07-20 00:09:47 -07:00
2021-09-07 09:57:49 -07:00
await cloudron . uninitialize ( ) ;
await database . uninitialize ( ) ;
await util . promisify ( gHttpServer . close . bind ( gHttpServer ) ) ( ) ;
2015-07-20 00:09:47 -07:00
2021-09-07 09:57:49 -07:00
gHttpServer = null ;
2015-07-20 00:09:47 -07:00
}