mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 11:43:44 -05:00
Merge pull request #1995 from overleaf/ta-conversion-metrics-query-fix
Pass conversion metrics query params to v1 GitOrigin-RevId: 0f6cb0118ac92896590fbe26b24a6b2a723e1f2c
This commit is contained in:
parent
d9b5941642
commit
90b1c4a23c
7 changed files with 1770 additions and 0 deletions
278
services/web/modules/launchpad/app/src/LaunchpadController.js
Normal file
278
services/web/modules/launchpad/app/src/LaunchpadController.js
Normal file
|
@ -0,0 +1,278 @@
|
|||
/* eslint-disable
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let LaunchpadController
|
||||
const Settings = require('settings-sharelatex')
|
||||
const Path = require('path')
|
||||
const Url = require('url')
|
||||
const logger = require('logger-sharelatex')
|
||||
const metrics = require('metrics-sharelatex')
|
||||
const UserRegistrationHandler = require('../../../../app/src/Features/User/UserRegistrationHandler')
|
||||
const EmailHandler = require('../../../../app/src/Features/Email/EmailHandler')
|
||||
const _ = require('underscore')
|
||||
const UserGetter = require('../../../../app/src/Features/User/UserGetter')
|
||||
const { User } = require('../../../../app/src/models/User')
|
||||
const AuthenticationController = require('../../../../app/src/Features/Authentication/AuthenticationController')
|
||||
|
||||
module.exports = LaunchpadController = {
|
||||
_getAuthMethod() {
|
||||
if (Settings.ldap) {
|
||||
return 'ldap'
|
||||
} else if (Settings.saml) {
|
||||
return 'saml'
|
||||
} else {
|
||||
return 'local'
|
||||
}
|
||||
},
|
||||
|
||||
launchpadPage(req, res, next) {
|
||||
// TODO: check if we're using external auth?
|
||||
// * how does all this work with ldap and saml?
|
||||
const sessionUser = AuthenticationController.getSessionUser(req)
|
||||
const authMethod = LaunchpadController._getAuthMethod()
|
||||
return LaunchpadController._atLeastOneAdminExists(function(
|
||||
err,
|
||||
adminUserExists
|
||||
) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
if (!sessionUser) {
|
||||
if (!adminUserExists) {
|
||||
return res.render(Path.resolve(__dirname, '../views/launchpad'), {
|
||||
adminUserExists,
|
||||
authMethod
|
||||
})
|
||||
} else {
|
||||
return AuthenticationController._redirectToLoginPage(req, res)
|
||||
}
|
||||
} else {
|
||||
return UserGetter.getUser(sessionUser._id, { isAdmin: 1 }, function(
|
||||
err,
|
||||
user
|
||||
) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
if (user && user.isAdmin) {
|
||||
return res.render(Path.resolve(__dirname, '../views/launchpad'), {
|
||||
adminUserExists,
|
||||
authMethod
|
||||
})
|
||||
} else {
|
||||
return res.redirect('/restricted')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
_atLeastOneAdminExists(callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err, exists) {}
|
||||
}
|
||||
return UserGetter.getUser(
|
||||
{ isAdmin: true },
|
||||
{ _id: 1, isAdmin: 1 },
|
||||
function(err, user) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
return callback(null, user != null)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
sendTestEmail(req, res, next) {
|
||||
const { email } = req.body
|
||||
if (!email) {
|
||||
logger.log({}, 'no email address supplied')
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
logger.log({ email }, 'sending test email')
|
||||
const emailOptions = { to: email }
|
||||
return EmailHandler.sendEmail('testEmail', emailOptions, function(err) {
|
||||
if (err != null) {
|
||||
logger.warn({ email }, 'error sending test email')
|
||||
return next(err)
|
||||
}
|
||||
logger.log({ email }, 'sent test email')
|
||||
return res.sendStatus(201)
|
||||
})
|
||||
},
|
||||
|
||||
registerExternalAuthAdmin(authMethod) {
|
||||
return function(req, res, next) {
|
||||
if (LaunchpadController._getAuthMethod() !== authMethod) {
|
||||
logger.log(
|
||||
{ authMethod },
|
||||
'trying to register external admin, but that auth service is not enabled, disallow'
|
||||
)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const { email } = req.body
|
||||
if (!email) {
|
||||
logger.log({ authMethod }, 'no email supplied, disallow')
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
|
||||
logger.log({ email }, 'attempted register first admin user')
|
||||
return LaunchpadController._atLeastOneAdminExists(function(err, exists) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
if (exists) {
|
||||
logger.log(
|
||||
{ email },
|
||||
'already have at least one admin user, disallow'
|
||||
)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const body = {
|
||||
email,
|
||||
password: 'password_here',
|
||||
first_name: email,
|
||||
last_name: ''
|
||||
}
|
||||
logger.log(
|
||||
{ body, authMethod },
|
||||
'creating admin account for specified external-auth user'
|
||||
)
|
||||
|
||||
return UserRegistrationHandler.registerNewUser(body, function(
|
||||
err,
|
||||
user
|
||||
) {
|
||||
if (err != null) {
|
||||
logger.warn(
|
||||
{ err, email, authMethod },
|
||||
'error with registerNewUser'
|
||||
)
|
||||
return next(err)
|
||||
}
|
||||
|
||||
return User.update(
|
||||
{ _id: user._id },
|
||||
{ $set: { isAdmin: true } },
|
||||
function(err) {
|
||||
if (err != null) {
|
||||
logger.warn(
|
||||
{ user_id: user._id, err },
|
||||
'error setting user to admin'
|
||||
)
|
||||
return next(err)
|
||||
}
|
||||
|
||||
AuthenticationController.setRedirectInSession(req, '/launchpad')
|
||||
logger.log(
|
||||
{ email, user_id: user._id, authMethod },
|
||||
'created first admin account'
|
||||
)
|
||||
|
||||
return res.json({ redir: '/launchpad', email })
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
registerAdmin(req, res, next) {
|
||||
const { email } = req.body
|
||||
const { password } = req.body
|
||||
if (!email || !password) {
|
||||
logger.log({}, 'must supply both email and password, disallow')
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
|
||||
logger.log({ email }, 'attempted register first admin user')
|
||||
return LaunchpadController._atLeastOneAdminExists(function(err, exists) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
if (exists) {
|
||||
logger.log(
|
||||
{ email: req.body.email },
|
||||
'already have at least one admin user, disallow'
|
||||
)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const body = { email, password }
|
||||
return UserRegistrationHandler.registerNewUser(body, function(err, user) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
logger.log({ user_id: user._id }, 'making user an admin')
|
||||
const proceed = () =>
|
||||
User.update({ _id: user._id }, { $set: { isAdmin: true } }, function(
|
||||
err
|
||||
) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ user_id: user._id, err },
|
||||
'error setting user to admin'
|
||||
)
|
||||
return next(err)
|
||||
}
|
||||
|
||||
AuthenticationController.setRedirectInSession(req, '/launchpad')
|
||||
logger.log(
|
||||
{ email, user_id: user._id },
|
||||
'created first admin account'
|
||||
)
|
||||
return res.json({
|
||||
redir: '',
|
||||
id: user._id.toString(),
|
||||
first_name: user.first_name,
|
||||
last_name: user.last_name,
|
||||
email: user.email,
|
||||
created: Date.now()
|
||||
})
|
||||
})
|
||||
|
||||
if (
|
||||
Settings.overleaf != null &&
|
||||
Settings.createV1AccountOnLogin != null
|
||||
) {
|
||||
logger.log(
|
||||
{ user_id: user._id },
|
||||
'Creating backing account in v1 for new admin user'
|
||||
)
|
||||
const SharelatexAuthController = require('../../../overleaf-integration/app/src/SharelatexAuth/SharelatexAuthController')
|
||||
return UserGetter.getUser(user._id, function(err, user) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
return SharelatexAuthController._createBackingAccountIfNeeded(
|
||||
user,
|
||||
req,
|
||||
function(err) {
|
||||
if (err != null) {
|
||||
return next(err)
|
||||
}
|
||||
return proceed()
|
||||
}
|
||||
)
|
||||
})
|
||||
} else {
|
||||
return proceed()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
53
services/web/modules/launchpad/app/src/LaunchpadRouter.js
Normal file
53
services/web/modules/launchpad/app/src/LaunchpadRouter.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* eslint-disable
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const logger = require('logger-sharelatex')
|
||||
const LaunchpadController = require('./LaunchpadController')
|
||||
const AuthenticationController = require('../../../../app/src/Features/Authentication/AuthenticationController')
|
||||
const AuthorizationMiddleware = require('../../../../app/src/Features/Authorization/AuthorizationMiddleware')
|
||||
|
||||
module.exports = {
|
||||
apply(webRouter, apiRouter) {
|
||||
logger.log({}, 'Init launchpad router')
|
||||
|
||||
webRouter.get('/launchpad', LaunchpadController.launchpadPage)
|
||||
webRouter.post(
|
||||
'/launchpad/register_admin',
|
||||
LaunchpadController.registerAdmin
|
||||
)
|
||||
webRouter.post(
|
||||
'/launchpad/register_ldap_admin',
|
||||
LaunchpadController.registerExternalAuthAdmin('ldap')
|
||||
)
|
||||
webRouter.post(
|
||||
'/launchpad/register_saml_admin',
|
||||
LaunchpadController.registerExternalAuthAdmin('saml')
|
||||
)
|
||||
webRouter.post(
|
||||
'/launchpad/send_test_email',
|
||||
AuthorizationMiddleware.ensureUserIsSiteAdmin,
|
||||
LaunchpadController.sendTestEmail
|
||||
)
|
||||
|
||||
if (AuthenticationController.addEndpointToLoginWhitelist != null) {
|
||||
AuthenticationController.addEndpointToLoginWhitelist('/launchpad')
|
||||
AuthenticationController.addEndpointToLoginWhitelist(
|
||||
'/launchpad/register_admin'
|
||||
)
|
||||
AuthenticationController.addEndpointToLoginWhitelist(
|
||||
'/launchpad/register_ldap_admin'
|
||||
)
|
||||
return AuthenticationController.addEndpointToLoginWhitelist(
|
||||
'/launchpad/register_saml_admin'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
267
services/web/modules/launchpad/app/views/launchpad.pug
Normal file
267
services/web/modules/launchpad/app/views/launchpad.pug
Normal file
|
@ -0,0 +1,267 @@
|
|||
extends ../../../../app/views/layout
|
||||
|
||||
block content
|
||||
|
||||
script(type="text/javascript").
|
||||
window.data = {
|
||||
adminUserExists: !{adminUserExists == true},
|
||||
ideJsPath: "!{buildJsPath('ide.js')}",
|
||||
authMethod: "!{authMethod}"
|
||||
}
|
||||
|
||||
script(type="text/javascript" src='/socket.io/socket.io.js')
|
||||
|
||||
style.
|
||||
hr { margin-bottom: 5px; }
|
||||
.status-check {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.alert { margin-top: 15px; margin-bottom: 15px; }
|
||||
a small { cursor: pointer; color: #a93529; }
|
||||
.launchpad-body img { width: 150px; margin-top: 15px; }
|
||||
|
||||
|
||||
.content.content-alt(ng-controller="LaunchpadController")
|
||||
.container(ng-cloak)
|
||||
.row
|
||||
.col-md-8.col-md-offset-2
|
||||
.card.launchpad-body
|
||||
.row
|
||||
.col-md-12
|
||||
.text-center
|
||||
h1 #{translate('welcome_to_sl')}
|
||||
p
|
||||
img(src=buildImgPath('/brand/lion.svg'))
|
||||
|
||||
<!-- wrapper -->
|
||||
.row
|
||||
.col-md-8.col-md-offset-2
|
||||
|
||||
|
||||
<!-- create first admin form -->
|
||||
.row(ng-if="shouldShowAdminForm()")
|
||||
.col-md-12
|
||||
h2 #{translate('create_first_admin_account')}
|
||||
|
||||
// Local Auth Form
|
||||
div(ng-if="authMethod == 'local'")
|
||||
form(async-form="register", name="registerForm", on-success="onCreateAdminSuccess"
|
||||
on-error="onCreateAdminError"
|
||||
action="/launchpad/register_admin", method="POST", ng-cloak)
|
||||
input(name='_csrf', type='hidden', value=csrfToken)
|
||||
form-messages(for="registerForm")
|
||||
.form-group
|
||||
label(for='email') #{translate("email")}
|
||||
input.form-control(
|
||||
type='email',
|
||||
name='email',
|
||||
placeholder="email@example.com"
|
||||
required,
|
||||
ng-model="email",
|
||||
ng-model-options="{ updateOn: 'blur' }",
|
||||
focus="true"
|
||||
)
|
||||
span.small.text-primary(ng-show="registerForm.email.$invalid && registerForm.email.$dirty")
|
||||
| #{translate("must_be_email_address")}
|
||||
.form-group
|
||||
label(for='password') #{translate("password")}
|
||||
input.form-control#passwordField(
|
||||
type='password',
|
||||
name='password',
|
||||
placeholder="********",
|
||||
required,
|
||||
ng-model="password",
|
||||
complex-password
|
||||
)
|
||||
span.small.text-primary(ng-show="registerForm.password.$error.complexPassword",
|
||||
ng-bind-html="complexPasswordErrorMessage")
|
||||
.actions
|
||||
button.btn-primary.btn(
|
||||
type='submit'
|
||||
ng-disabled="registerForm.inflight || registerForm.password.$error.required|| registerForm.password.$error.complexPassword || createAdminSuccess"
|
||||
)
|
||||
span(ng-show="!registerForm.inflight") #{translate("register")}
|
||||
span(ng-show="registerForm.inflight") #{translate("registering")}...
|
||||
|
||||
// Ldap Form
|
||||
div(ng-if="authMethod == 'ldap'")
|
||||
h3 #{translate('ldap')}
|
||||
p
|
||||
| #{translate('ldap_create_admin_instructions')}
|
||||
|
||||
form(async-form="register", name="registerLdapForm", on-success="onCreateAdminSuccess"
|
||||
on-error="onCreateAdminError"
|
||||
action="/launchpad/register_ldap_admin", method="POST", ng-cloak)
|
||||
input(name='_csrf', type='hidden', value=csrfToken)
|
||||
form-messages(for="registerLdapForm")
|
||||
.form-group
|
||||
label(for='email') #{translate("email")}
|
||||
input.form-control(
|
||||
type='email',
|
||||
name='email',
|
||||
placeholder="email@example.com"
|
||||
required,
|
||||
ng-model="email",
|
||||
ng-model-options="{ updateOn: 'blur' }",
|
||||
focus="true"
|
||||
)
|
||||
span.small.text-primary(ng-show="registerLdapForm.email.$invalid && registerLdapForm.email.$dirty")
|
||||
| #{translate("must_be_email_address")}
|
||||
.actions
|
||||
button.btn-primary.btn(
|
||||
type='submit'
|
||||
ng-disabled="registerLdapForm.inflight || registerLdapForm.password.$error.required|| registerLdapForm.password.$error.complexPassword || createAdminSuccess"
|
||||
)
|
||||
span(ng-show="!registerLdapForm.inflight") #{translate("register")}
|
||||
span(ng-show="registerLdapForm.inflight") #{translate("registering")}...
|
||||
|
||||
|
||||
// Saml Form
|
||||
div(ng-if="authMethod == 'saml'")
|
||||
h3 #{translate('saml')}
|
||||
p
|
||||
| #{translate('saml_create_admin_instructions')}
|
||||
|
||||
form(async-form="register", name="registerSamlForm", on-success="onCreateAdminSuccess"
|
||||
on-error="onCreateAdminError"
|
||||
action="/launchpad/register_saml_admin", method="POST", ng-cloak)
|
||||
input(name='_csrf', type='hidden', value=csrfToken)
|
||||
form-messages(for="registerSamlForm")
|
||||
.form-group
|
||||
label(for='email') #{translate("email")}
|
||||
input.form-control(
|
||||
type='email',
|
||||
name='email',
|
||||
placeholder="email@example.com"
|
||||
required,
|
||||
ng-model="email",
|
||||
ng-model-options="{ updateOn: 'blur' }",
|
||||
focus="true"
|
||||
)
|
||||
span.small.text-primary(ng-show="registerSamlForm.email.$invalid && registerSamlForm.email.$dirty")
|
||||
| #{translate("must_be_email_address")}
|
||||
.actions
|
||||
button.btn-primary.btn(
|
||||
type='submit'
|
||||
ng-disabled="registerSamlForm.inflight || registerSamlForm.password.$error.required|| registerSamlForm.password.$error.complexPassword || createAdminSuccess"
|
||||
)
|
||||
span(ng-show="!registerSamlForm.inflight") #{translate("register")}
|
||||
span(ng-show="registerSamlForm.inflight") #{translate("registering")}...
|
||||
|
||||
|
||||
<!-- success message -->
|
||||
.row(ng-if="createAdminSuccess")
|
||||
.col-md-12.text-center
|
||||
.alert.alert-success
|
||||
| !{translate('admin_user_created_message', {link: '/login?redir=/launchpad'})}
|
||||
|
||||
<!-- error message -->
|
||||
.row(ng-if="createAdminError")
|
||||
.col-md-12.text-center
|
||||
.alert.alert-danger
|
||||
| #{translate('generic_something_went_wrong')}
|
||||
|
||||
br
|
||||
|
||||
<!-- status indicators -->
|
||||
div(ng-if="!shouldShowAdminForm()")
|
||||
.row
|
||||
.col-md-12.status-indicators
|
||||
|
||||
h2 #{translate('status_checks')}
|
||||
|
||||
<!-- ide js -->
|
||||
.row.status-check
|
||||
.col-sm-5
|
||||
| #{translate('editor_resources')}
|
||||
.col-sm-7
|
||||
div(ng-switch="statusChecks.ideJs.status")
|
||||
|
||||
span(ng-switch-when="inflight")
|
||||
i.fa.fa-fw.fa-spinner.fa-spin
|
||||
span #{translate('checking')}
|
||||
|
||||
span(ng-switch-when="ok")
|
||||
i.fa.fa-check
|
||||
span #{translate('ok')}
|
||||
a(ng-click="tryFetchIdeJs()")
|
||||
small #{translate('retry')}
|
||||
|
||||
span(ng-switch-when="error")
|
||||
i.fa.fa-exclamation
|
||||
span #{translate('error')}
|
||||
a(ng-click="tryFetchIdeJs()")
|
||||
small #{translate('retry')}
|
||||
div.alert.alert-danger
|
||||
| {{ statusChecks.ideJs.error }}
|
||||
|
||||
|
||||
<!-- websocket -->
|
||||
.row.status-check
|
||||
.col-sm-5
|
||||
| #{translate('websockets')}
|
||||
.col-sm-7
|
||||
div(ng-switch="statusChecks.websocket.status")
|
||||
|
||||
span(ng-switch-when="inflight")
|
||||
i.fa.fa-fw.fa-spinner.fa-spin
|
||||
span #{translate('checking')}
|
||||
|
||||
span(ng-switch-when="ok")
|
||||
i.fa.fa-check
|
||||
span #{translate('ok')}
|
||||
a(ng-click="tryOpenWebSocket()")
|
||||
small #{translate('retry')}
|
||||
|
||||
span(ng-switch-when="error")
|
||||
i.fa.fa-exclamation
|
||||
span #{translate('error')}
|
||||
a(ng-click="tryOpenWebSocket()")
|
||||
small #{translate('retry')}
|
||||
div.alert.alert-danger
|
||||
| {{ statusChecks.websocket.error }}
|
||||
|
||||
|
||||
<!-- break -->
|
||||
hr
|
||||
|
||||
<!-- other actions -->
|
||||
.row
|
||||
.col-md-12
|
||||
h2 #{translate('other_actions')}
|
||||
|
||||
h3 #{translate('send_test_email')}
|
||||
form.form
|
||||
.form-group
|
||||
label(for="emailInput") Email
|
||||
input(type="text", name="emailInput" ng-model="testEmail.emailAddress").form-control
|
||||
button(ng-click="sendTestEmail()", ng-disabled="testEmail.inflight").btn.btn-primary
|
||||
span(ng-show="!testEmail.inflight") #{translate("send")}
|
||||
span(ng-show="testEmail.inflight") #{translate("sending")}...
|
||||
div(ng-if="testEmail.status == 'ok'")
|
||||
.alert.alert-success
|
||||
| #{translate('email_sent')}
|
||||
div(ng-if="testEmail.status == 'error'")
|
||||
.alert.alert-danger
|
||||
| #{translate('generic_something_went_wrong')}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- break -->
|
||||
hr
|
||||
|
||||
|
||||
<!-- Go to ShareLaTex -->
|
||||
.row
|
||||
.col-md-12
|
||||
.text-center
|
||||
br
|
||||
p
|
||||
a(href="/admin").btn.btn-md
|
||||
| Go To Admin Panel
|
||||
|
|
||||
a(href="/project").btn.btn-md.btn-primary
|
||||
| Start Using ShareLaTeX
|
||||
br
|
9
services/web/modules/launchpad/index.js
Normal file
9
services/web/modules/launchpad/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* eslint-disable
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
let Launchpad
|
||||
const LaunchpadRouter = require('./app/src/LaunchpadRouter')
|
||||
|
||||
module.exports = Launchpad = { router: LaunchpadRouter }
|
|
@ -0,0 +1,155 @@
|
|||
/* eslint-disable
|
||||
max-len,
|
||||
no-return-assign,
|
||||
no-undef,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
define(['base'], App =>
|
||||
App.controller('LaunchpadController', function($scope, $http, $timeout) {
|
||||
$scope.adminUserExists = window.data.adminUserExists
|
||||
$scope.ideJsPath = window.data.ideJsPath
|
||||
$scope.authMethod = window.data.authMethod
|
||||
|
||||
$scope.createAdminSuccess = null
|
||||
$scope.createAdminError = null
|
||||
|
||||
$scope.statusChecks = {
|
||||
ideJs: { status: 'inflight', error: null },
|
||||
websocket: { status: 'inflight', error: null },
|
||||
healthCheck: { status: 'inflight', error: null }
|
||||
}
|
||||
|
||||
$scope.testEmail = {
|
||||
emailAddress: '',
|
||||
inflight: false,
|
||||
status: null // | 'ok' | 'success'
|
||||
}
|
||||
|
||||
$scope.shouldShowAdminForm = () => !$scope.adminUserExists
|
||||
|
||||
$scope.onCreateAdminSuccess = function(response) {
|
||||
const { status } = response
|
||||
if (status >= 200 && status < 300) {
|
||||
return ($scope.createAdminSuccess = true)
|
||||
}
|
||||
}
|
||||
|
||||
$scope.onCreateAdminError = () => ($scope.createAdminError = true)
|
||||
|
||||
$scope.sendTestEmail = function() {
|
||||
$scope.testEmail.inflight = true
|
||||
$scope.testEmail.status = null
|
||||
return $http
|
||||
.post('/launchpad/send_test_email', {
|
||||
email: $scope.testEmail.emailAddress,
|
||||
_csrf: window.csrfToken
|
||||
})
|
||||
.then(function(response) {
|
||||
const { status } = response
|
||||
$scope.testEmail.inflight = false
|
||||
if (status >= 200 && status < 300) {
|
||||
return ($scope.testEmail.status = 'ok')
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
$scope.testEmail.inflight = false
|
||||
return ($scope.testEmail.status = 'error')
|
||||
})
|
||||
}
|
||||
|
||||
$scope.tryFetchIdeJs = function() {
|
||||
$scope.statusChecks.ideJs.status = 'inflight'
|
||||
return $timeout(
|
||||
() =>
|
||||
$http
|
||||
.get($scope.ideJsPath)
|
||||
.then(function(response) {
|
||||
const { status } = response
|
||||
if (status >= 200 && status < 300) {
|
||||
return ($scope.statusChecks.ideJs.status = 'ok')
|
||||
}
|
||||
})
|
||||
.catch(function(response) {
|
||||
const { status } = response
|
||||
$scope.statusChecks.ideJs.status = 'error'
|
||||
return ($scope.statusChecks.ideJs.error = new Error(
|
||||
`Http status: ${status}`
|
||||
))
|
||||
}),
|
||||
|
||||
1000
|
||||
)
|
||||
}
|
||||
|
||||
$scope.tryOpenWebSocket = function() {
|
||||
$scope.statusChecks.websocket.status = 'inflight'
|
||||
return $timeout(function() {
|
||||
if (typeof io === 'undefined' || io === null) {
|
||||
$scope.statusChecks.websocket.status = 'error'
|
||||
$scope.statusChecks.websocket.error = 'socket.io not loaded'
|
||||
return
|
||||
}
|
||||
const socket = io.connect(
|
||||
null,
|
||||
{
|
||||
reconnect: false,
|
||||
'connect timeout': 30 * 1000,
|
||||
'force new connection': true
|
||||
}
|
||||
)
|
||||
|
||||
socket.on('connectionAccepted', function() {
|
||||
$scope.statusChecks.websocket.status = 'ok'
|
||||
return $scope.$apply(function() {})
|
||||
})
|
||||
|
||||
socket.on('connectionRejected', function(err) {
|
||||
$scope.statusChecks.websocket.status = 'error'
|
||||
$scope.statusChecks.websocket.error = err
|
||||
return $scope.$apply(function() {})
|
||||
})
|
||||
|
||||
return socket.on('connect_failed', function(err) {
|
||||
$scope.statusChecks.websocket.status = 'error'
|
||||
$scope.statusChecks.websocket.error = err
|
||||
return $scope.$apply(function() {})
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
$scope.tryHealthCheck = function() {
|
||||
$scope.statusChecks.healthCheck.status = 'inflight'
|
||||
return $http
|
||||
.get('/health_check')
|
||||
.then(function(response) {
|
||||
const { status } = response
|
||||
if (status >= 200 && status < 300) {
|
||||
return ($scope.statusChecks.healthCheck.status = 'ok')
|
||||
}
|
||||
})
|
||||
.catch(function(response) {
|
||||
const { status } = response
|
||||
$scope.statusChecks.healthCheck.status = 'error'
|
||||
return ($scope.statusChecks.healthCheck.error = new Error(
|
||||
`Http status: ${status}`
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
$scope.runStatusChecks = function() {
|
||||
$timeout(() => $scope.tryFetchIdeJs(), 1000)
|
||||
return $timeout(() => $scope.tryOpenWebSocket(), 2000)
|
||||
}
|
||||
|
||||
// kick off the status checks on load
|
||||
if ($scope.adminUserExists) {
|
||||
return $scope.runStatusChecks()
|
||||
}
|
||||
}))
|
3
services/web/modules/launchpad/public/src/main/index.js
Normal file
3
services/web/modules/launchpad/public/src/main/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Sanity-check the conversion and remove this comment.
|
||||
define(['main/launchpad/controllers/LaunchpadController'], function() {})
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue