mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-14 20:40:17 -05:00
Merge pull request #18316 from overleaf/jpa-host-admin
[server-ce] e2e tests: add capability for reconfiguring the instance GitOrigin-RevId: 44ec800b5b37497b3122310a94f637c24ff2667a
This commit is contained in:
parent
22257cf037
commit
8eb8b233c0
19 changed files with 1144 additions and 177 deletions
|
@ -1,3 +1,4 @@
|
|||
.DS_Store
|
||||
.git/
|
||||
services/git-bridge
|
||||
server-ce/test
|
||||
|
|
|
@ -15,11 +15,6 @@ ADD package.json package-lock.json /overleaf/
|
|||
ADD libraries/ /overleaf/libraries/
|
||||
ADD services/ /overleaf/services/
|
||||
|
||||
# Store the revision
|
||||
# ------------------
|
||||
ARG MONOREPO_REVISION
|
||||
RUN echo "monorepo-server-ce,$MONOREPO_REVISION" > /var/www/revisions.txt
|
||||
|
||||
# Add npm patches
|
||||
# -----------------------
|
||||
ADD patches/ /overleaf/patches
|
||||
|
@ -115,3 +110,9 @@ ENV LOG_LEVEL "info"
|
|||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["/sbin/my_init"]
|
||||
|
||||
# Store the revision
|
||||
# ------------------
|
||||
# This should be the last step to optimize docker image caching.
|
||||
ARG MONOREPO_REVISION
|
||||
RUN echo "monorepo-server-ce,$MONOREPO_REVISION" > /var/www/revisions.txt
|
||||
|
|
8
server-ce/test/Dockerfile
Normal file
8
server-ce/test/Dockerfile
Normal file
|
@ -0,0 +1,8 @@
|
|||
FROM node:18.20.2
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \
|
||||
&& echo \
|
||||
"deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y docker-ce-cli docker-compose-plugin \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
|
@ -1,13 +1,22 @@
|
|||
all: test-e2e
|
||||
|
||||
# We are updating the docker compose config via the host-admin service.
|
||||
# The host-admin service is running inside docker and has its own file-system layout.
|
||||
# We need to have both file-system layouts agree on the path for the docker compose project.
|
||||
# Notable the container labels com.docker.compose.project.working_dir and com.docker.compose.project.config_files need to match when creating containers from the docker host (how you started things) and from host-admin (how tests reconfigure the instance).
|
||||
export PWD = $(shell pwd)
|
||||
|
||||
test-e2e:
|
||||
docker compose down -v -t 0
|
||||
docker compose -f docker-compose.yml run --rm e2e
|
||||
docker compose down -v -t 0
|
||||
docker compose up --build --no-log-prefix --exit-code-from=e2e e2e
|
||||
|
||||
test-e2e-open:
|
||||
docker compose down -v -t 0
|
||||
docker compose -f docker-compose.yml run --rm e2e-open
|
||||
docker compose down -v -t 0
|
||||
docker compose up --build --no-log-prefix --exit-code-from=e2e-open e2e-open
|
||||
|
||||
clean:
|
||||
docker compose down --volumes --timeout 0
|
||||
|
||||
prefetch:
|
||||
docker compose pull e2e mongo redis
|
||||
docker compose build
|
||||
|
||||
.PHONY: test-e2e test-e2e-open
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { login } from './helpers/login'
|
||||
import { ensureUserExists, login } from './helpers/login'
|
||||
import { startWith } from './helpers/config'
|
||||
|
||||
describe('Accounts', function () {
|
||||
startWith({})
|
||||
ensureUserExists({ email: 'user@example.com' })
|
||||
|
||||
it('can log in and out', function () {
|
||||
login('user@example.com')
|
||||
cy.visit('/project')
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
import { login } from './helpers/login'
|
||||
import { ensureUserExists, login } from './helpers/login'
|
||||
import { createProject } from './helpers/project'
|
||||
import { startWith } from './helpers/config'
|
||||
|
||||
describe('Project creation and compilation', function () {
|
||||
startWith({})
|
||||
ensureUserExists({ email: 'user@example.com' })
|
||||
ensureUserExists({ email: 'collaborator@example.com' })
|
||||
|
||||
it('users can create project and compile it', function () {
|
||||
login('user@example.com')
|
||||
cy.visit('/project')
|
||||
// this is the first project created, the welcome screen is displayed instead of the project list
|
||||
createProject('test-project', { isFirstProject: true })
|
||||
createProject('test-project')
|
||||
cy.url().should('match', /\/project\/[a-fA-F0-9]{24}/)
|
||||
cy.findByText('\\maketitle').parent().click()
|
||||
cy.findByText('\\maketitle').parent().type('\n\\section{{}Test Section}')
|
||||
|
|
25
server-ce/test/customization.spec.ts
Normal file
25
server-ce/test/customization.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { startWith } from './helpers/config'
|
||||
|
||||
describe('Customization', () => {
|
||||
startWith({
|
||||
vars: {
|
||||
OVERLEAF_APP_NAME: 'CUSTOM APP NAME',
|
||||
OVERLEAF_LEFT_FOOTER: JSON.stringify([{ text: 'CUSTOM LEFT FOOTER' }]),
|
||||
OVERLEAF_RIGHT_FOOTER: JSON.stringify([{ text: 'CUSTOM RIGHT FOOTER' }]),
|
||||
},
|
||||
})
|
||||
|
||||
it('should display custom name', () => {
|
||||
cy.visit('/')
|
||||
cy.get('nav').findByText('CUSTOM APP NAME')
|
||||
})
|
||||
|
||||
it('should display custom left footer', () => {
|
||||
cy.visit('/')
|
||||
cy.get('footer').findByText('CUSTOM LEFT FOOTER')
|
||||
})
|
||||
it('should display custom right footer', () => {
|
||||
cy.visit('/')
|
||||
cy.get('footer').findByText('CUSTOM RIGHT FOOTER')
|
||||
})
|
||||
})
|
|
@ -3,8 +3,9 @@ const { defineConfig } = require('cypress')
|
|||
const specPattern = process.env.SPEC_PATTERN || './**/*.spec.{js,ts,tsx}'
|
||||
|
||||
module.exports = defineConfig({
|
||||
defaultCommandTimeout: 10_000,
|
||||
fixturesFolder: 'cypress/fixtures',
|
||||
video: !!process.env.CI,
|
||||
video: process.env.CYPRESS_VIDEO === 'true',
|
||||
screenshotsFolder: 'cypress/results',
|
||||
videosFolder: 'cypress/results',
|
||||
videoUploadOnPasses: false,
|
||||
|
|
3
server-ce/test/cypress/.gitignore
vendored
3
server-ce/test/cypress/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
results/
|
||||
downloads/
|
||||
results/
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
version: '2.2'
|
||||
services:
|
||||
sharelatex:
|
||||
image: ${IMAGE_TAG:-sharelatex/sharelatex:latest}
|
||||
container_name: sharelatex
|
||||
image: ${IMAGE_TAG_CE:-sharelatex/sharelatex:latest}
|
||||
# TODO(das7pad): increase timeout after speeding up the graceful shutdown procedure
|
||||
# stop_grace_period: 60s
|
||||
stop_grace_period: 0s
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_started
|
||||
ports:
|
||||
- 127.0.0.2:80:80
|
||||
links:
|
||||
- mongo
|
||||
- redis
|
||||
host-admin:
|
||||
# The host-admin service initiates the mongo replica set
|
||||
condition: service_healthy
|
||||
environment:
|
||||
OVERLEAF_APP_NAME: Overleaf Community Edition
|
||||
OVERLEAF_MONGO_URL: mongodb://mongo/sharelatex?directConnection=true
|
||||
|
@ -23,36 +23,27 @@ services:
|
|||
EMAIL_CONFIRMATION_DISABLED: 'true'
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost:3000/status || exit 1
|
||||
interval: 10s
|
||||
interval: 3s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
volumes:
|
||||
- ./util/seed-mongo.sh:/etc/my_init.d/99_seed-mongo.sh
|
||||
- ./util/seed-mongo.js:/overleaf/services/web/modules/server-ce-scripts/scripts/seed-mongo.js
|
||||
|
||||
mongo:
|
||||
image: mongo:5.0.17
|
||||
container_name: mongo
|
||||
command: '--replSet overleaf'
|
||||
expose:
|
||||
- 27017
|
||||
healthcheck:
|
||||
# FIXME: silly hack to make sure replicaset is initialized
|
||||
test: 'echo ''rs.initiate({ _id: "overleaf", members: [{ _id: 0, host: "mongo:27017" }] })'' | mongo localhost:27017/test --quiet'
|
||||
test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7.2.1
|
||||
container_name: redis
|
||||
expose:
|
||||
- 6379
|
||||
|
||||
e2e:
|
||||
image: cypress/included:13.6.6
|
||||
links:
|
||||
- sharelatex
|
||||
stop_grace_period: 0s
|
||||
entrypoint: npm
|
||||
command: run cypress:run
|
||||
working_dir: /e2e
|
||||
volumes:
|
||||
- ./:/e2e
|
||||
|
@ -62,13 +53,14 @@ services:
|
|||
depends_on:
|
||||
sharelatex:
|
||||
condition: service_healthy
|
||||
host-admin:
|
||||
condition: service_healthy
|
||||
|
||||
e2e-open:
|
||||
image: cypress/included:13.6.6
|
||||
stop_grace_period: 0s
|
||||
entrypoint: npm
|
||||
command: run cypress:open
|
||||
links:
|
||||
- sharelatex
|
||||
working_dir: /e2e
|
||||
volumes:
|
||||
- ./:/e2e
|
||||
|
@ -81,3 +73,27 @@ services:
|
|||
depends_on:
|
||||
sharelatex:
|
||||
condition: service_healthy
|
||||
host-admin:
|
||||
condition: service_healthy
|
||||
|
||||
host-admin:
|
||||
build: .
|
||||
entrypoint: ["node", "--watch", "host-admin.js"]
|
||||
# See comment in Makefile regarding matching file paths
|
||||
working_dir: $PWD
|
||||
volumes:
|
||||
- $PWD:$PWD
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
stop_grace_period: 0s
|
||||
environment:
|
||||
PWD:
|
||||
IMAGE_TAG_CE: ${IMAGE_TAG_CE:-sharelatex/sharelatex:latest}
|
||||
IMAGE_TAG_PRO: ${IMAGE_TAG_PRO:-quay.io/sharelatex/sharelatex-pro:latest}
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost/status || exit 1
|
||||
interval: 3s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
|
|
16
server-ce/test/helpers/config.ts
Normal file
16
server-ce/test/helpers/config.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { reconfigure } from './hostAdminClient'
|
||||
|
||||
let lastConfig: string
|
||||
|
||||
export function startWith({ pro = false, version = 'latest', vars = {} }) {
|
||||
before(async function () {
|
||||
const cfg = JSON.stringify({ pro, version, vars })
|
||||
if (lastConfig === cfg) return
|
||||
|
||||
this.timeout(100 * 1000)
|
||||
await reconfigure({ pro, version, vars })
|
||||
lastConfig = cfg
|
||||
})
|
||||
}
|
||||
|
||||
export { reconfigure }
|
84
server-ce/test/helpers/hostAdminClient.ts
Normal file
84
server-ce/test/helpers/hostAdminClient.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
export async function setVars(vars = {}) {
|
||||
return await fetchJSON('http://host-admin/set/vars', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ vars, path: 'docker-compose.yml' }),
|
||||
})
|
||||
}
|
||||
|
||||
export async function setVersion({ pro = false, version = 'latest' }) {
|
||||
return await fetchJSON('http://host-admin/set/version', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
pro,
|
||||
version,
|
||||
path: 'docker-compose.yml',
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export async function dockerCompose(cmd: string, ...args: string[]) {
|
||||
return await fetchJSON(`http://host-admin/docker/compose/${cmd}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
args,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export async function mongoInit() {
|
||||
return await fetchJSON('http://host-admin/mongo/init', {
|
||||
method: 'POST',
|
||||
})
|
||||
}
|
||||
|
||||
export async function reconfigure({
|
||||
pro = false,
|
||||
version = 'latest',
|
||||
vars = {},
|
||||
}) {
|
||||
return await fetchJSON('http://host-admin/reconfigure', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
pro,
|
||||
version,
|
||||
vars,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
async function fetchJSON(
|
||||
input: RequestInfo,
|
||||
init?: RequestInit
|
||||
): Promise<{ stdout: string; stderr: string }> {
|
||||
if (init?.body) {
|
||||
init.headers = { 'Content-Type': 'application/json' }
|
||||
}
|
||||
const res = await fetch(input, init)
|
||||
const { error, stdout, stderr } = await res.json()
|
||||
if (error) {
|
||||
console.error(input, init, 'failed:', error)
|
||||
const err = new Error(error.message)
|
||||
Object.assign(err, error)
|
||||
throw err
|
||||
}
|
||||
return { stdout, stderr }
|
||||
}
|
||||
|
||||
export async function runScript({
|
||||
cwd,
|
||||
script,
|
||||
args = [],
|
||||
}: {
|
||||
cwd: string
|
||||
script: string
|
||||
args?: string[]
|
||||
}) {
|
||||
return await fetchJSON('http://host-admin/run/script', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
cwd,
|
||||
script,
|
||||
args,
|
||||
}),
|
||||
})
|
||||
}
|
|
@ -1,4 +1,57 @@
|
|||
export function login(username: string, password = 'Passw0rd!') {
|
||||
import { runScript } from './hostAdminClient'
|
||||
|
||||
const DEFAULT_PASSWORD = 'Passw0rd!'
|
||||
|
||||
const createdUsers = new Set<string>()
|
||||
|
||||
async function createMongoUser({
|
||||
email,
|
||||
isAdmin = false,
|
||||
}: {
|
||||
email: string
|
||||
isAdmin?: boolean
|
||||
}) {
|
||||
const t0 = Date.now()
|
||||
const { stdout } = await runScript({
|
||||
cwd: 'services/web',
|
||||
script: 'modules/server-ce-scripts/scripts/create-user.js',
|
||||
args: [`--email=${email}`, `--admin=${isAdmin}`],
|
||||
})
|
||||
const [url] = stdout.match(/\/user\/activate\?token=\S+/)!
|
||||
const userId = new URL(url, location.origin).searchParams.get('user_id')!
|
||||
const signupDate = parseInt(userId.slice(0, 8), 16) * 1000
|
||||
if (signupDate < t0) {
|
||||
return { url, exists: true }
|
||||
}
|
||||
return { url, exists: false }
|
||||
}
|
||||
|
||||
export function ensureUserExists({
|
||||
email,
|
||||
password = DEFAULT_PASSWORD,
|
||||
isAdmin = false,
|
||||
}: {
|
||||
email: string
|
||||
password?: string
|
||||
isAdmin?: boolean
|
||||
}) {
|
||||
let url: string
|
||||
let exists: boolean
|
||||
before(async function () {
|
||||
exists = createdUsers.has(email)
|
||||
if (exists) return
|
||||
;({ url, exists } = await createMongoUser({ email, isAdmin }))
|
||||
})
|
||||
before(function () {
|
||||
if (exists) return
|
||||
activateUser(url, password)
|
||||
cy.then(() => {
|
||||
createdUsers.add(email)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function login(username: string, password = DEFAULT_PASSWORD) {
|
||||
cy.session([username, password, new Date()], () => {
|
||||
cy.visit('/login')
|
||||
cy.get('input[name="email"]').type(username)
|
||||
|
@ -7,3 +60,16 @@ export function login(username: string, password = 'Passw0rd!') {
|
|||
cy.url().should('contain', '/project')
|
||||
})
|
||||
}
|
||||
|
||||
export function activateUser(url: string, password = DEFAULT_PASSWORD) {
|
||||
cy.session(url, () => {
|
||||
cy.visit(url)
|
||||
cy.url().then(url => {
|
||||
if (url.includes('/login')) return
|
||||
cy.url().should('contain', '/user/activate')
|
||||
cy.get('input[name="password"]').type(password)
|
||||
cy.findByRole('button', { name: 'Activate' }).click()
|
||||
cy.url().should('contain', '/project')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,18 +2,13 @@ export function createProject(
|
|||
name: string,
|
||||
{
|
||||
type = 'Blank Project',
|
||||
isFirstProject,
|
||||
}: {
|
||||
type?: 'Blank Project' | 'Example Project'
|
||||
isFirstProject?: boolean
|
||||
} = {}
|
||||
): Cypress.Chainable<string> {
|
||||
if (isFirstProject) {
|
||||
cy.findByText('Create a new project').click()
|
||||
} else {
|
||||
// FIXME: This should be be a data-test-id shared between the welcome page and project list
|
||||
cy.get('.new-project-button').first().click()
|
||||
}
|
||||
cy.findAllByRole('button')
|
||||
.contains(/new project/i)
|
||||
.click()
|
||||
// FIXME: This should only look in the left menu
|
||||
cy.findAllByText(type).first().click()
|
||||
cy.findByRole('dialog').within(() => {
|
||||
|
|
279
server-ce/test/host-admin.js
Normal file
279
server-ce/test/host-admin.js
Normal file
|
@ -0,0 +1,279 @@
|
|||
const fs = require('fs')
|
||||
const { execFile } = require('child_process')
|
||||
const express = require('express')
|
||||
const bodyParser = require('body-parser')
|
||||
const {
|
||||
celebrate: validate,
|
||||
Joi,
|
||||
errors: handleValidationErrors,
|
||||
} = require('celebrate')
|
||||
const YAML = require('js-yaml')
|
||||
|
||||
const FILES = {
|
||||
DOCKER_COMPOSE: 'docker-compose.override.yml',
|
||||
}
|
||||
const IMAGES = {
|
||||
CE: process.env.IMAGE_TAG_CE.replace(/:.+/, ''),
|
||||
PRO: process.env.IMAGE_TAG_PRO.replace(/:.+/, ''),
|
||||
}
|
||||
|
||||
let mongoIsInitialized = false
|
||||
|
||||
function readDockerComposeOverride() {
|
||||
try {
|
||||
return YAML.load(fs.readFileSync(FILES.DOCKER_COMPOSE, 'utf-8'))
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error
|
||||
}
|
||||
return {
|
||||
services: {
|
||||
sharelatex: {
|
||||
environment: {},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeDockerComposeOverride(cfg) {
|
||||
fs.writeFileSync(FILES.DOCKER_COMPOSE, YAML.dump(cfg))
|
||||
}
|
||||
|
||||
const app = express()
|
||||
app.get('/status', (req, res) => {
|
||||
res.send('host-admin is up')
|
||||
})
|
||||
|
||||
app.use(bodyParser.json())
|
||||
app.use((req, res, next) => {
|
||||
// Basic access logs
|
||||
console.log(req.method, req.url, req.body)
|
||||
// Add CORS headers
|
||||
res.setHeader('Access-Control-Allow-Origin', 'http://sharelatex')
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
|
||||
next()
|
||||
})
|
||||
|
||||
app.post(
|
||||
'/run/script',
|
||||
validate(
|
||||
{
|
||||
body: {
|
||||
cwd: Joi.string().required(),
|
||||
script: Joi.string().required(),
|
||||
args: Joi.array().items(Joi.string()),
|
||||
},
|
||||
},
|
||||
{ allowUnknown: false }
|
||||
),
|
||||
(req, res) => {
|
||||
const { cwd, script, args } = req.body
|
||||
|
||||
execFile(
|
||||
'docker',
|
||||
[
|
||||
'compose',
|
||||
'exec',
|
||||
'sharelatex',
|
||||
'bash',
|
||||
'-c',
|
||||
`source /etc/container_environment.sh && source /etc/overleaf/env.sh && cd ${JSON.stringify(cwd)} && node ${JSON.stringify(script)} ${args.map(a => JSON.stringify(a)).join(' ')}`,
|
||||
],
|
||||
(error, stdout, stderr) => {
|
||||
res.json({
|
||||
error,
|
||||
stdout,
|
||||
stderr,
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
function setVersionDockerCompose({ pro, version }) {
|
||||
const cfg = readDockerComposeOverride()
|
||||
|
||||
cfg.services.sharelatex.image = `${pro ? IMAGES.PRO : IMAGES.CE}:${version}`
|
||||
|
||||
writeDockerComposeOverride(cfg)
|
||||
}
|
||||
|
||||
app.post(
|
||||
'/set/version',
|
||||
validate(
|
||||
{
|
||||
body: {
|
||||
pro: Joi.boolean(),
|
||||
version: Joi.string().required(),
|
||||
path: Joi.allow(
|
||||
'docker-compose.yml'
|
||||
// When extending testing for Toolkit:
|
||||
// 'config/version'
|
||||
),
|
||||
},
|
||||
},
|
||||
{ allowUnknown: false }
|
||||
),
|
||||
(req, res) => {
|
||||
const { pro, version } = req.body
|
||||
if (req.body.path === 'docker-compose.yml') {
|
||||
try {
|
||||
setVersionDockerCompose({ pro, version })
|
||||
} catch (error) {
|
||||
return res.json({ error })
|
||||
}
|
||||
}
|
||||
res.json({})
|
||||
}
|
||||
)
|
||||
|
||||
const allowedVars = Joi.object().keys({
|
||||
OVERLEAF_APP_NAME: Joi.string(),
|
||||
OVERLEAF_LEFT_FOOTER: Joi.string(),
|
||||
OVERLEAF_RIGHT_FOOTER: Joi.string(),
|
||||
})
|
||||
|
||||
function setVarsDockerCompose({ vars }) {
|
||||
const cfg = readDockerComposeOverride()
|
||||
|
||||
cfg.services.sharelatex.environment = vars
|
||||
|
||||
writeDockerComposeOverride(cfg)
|
||||
}
|
||||
|
||||
app.post(
|
||||
'/set/vars',
|
||||
validate(
|
||||
{
|
||||
body: {
|
||||
vars: allowedVars,
|
||||
path: Joi.allow(
|
||||
'docker-compose.yml'
|
||||
// When extending the testing for Toolkit:
|
||||
// 'overleaf.rc', 'variables.env'
|
||||
),
|
||||
},
|
||||
},
|
||||
{ allowUnknown: false }
|
||||
),
|
||||
(req, res) => {
|
||||
if (req.body.path === 'docker-compose.yml') {
|
||||
const { vars } = req.body
|
||||
try {
|
||||
setVarsDockerCompose({ vars })
|
||||
} catch (error) {
|
||||
return res.json({ error })
|
||||
}
|
||||
}
|
||||
res.json({})
|
||||
}
|
||||
)
|
||||
|
||||
app.post(
|
||||
'/docker/compose/:cmd',
|
||||
validate(
|
||||
{
|
||||
body: {
|
||||
args: Joi.array().allow(
|
||||
'--detach',
|
||||
'--wait',
|
||||
'--volumes',
|
||||
'--timeout',
|
||||
'0',
|
||||
'sharelatex',
|
||||
'mongo',
|
||||
'redis'
|
||||
),
|
||||
},
|
||||
params: {
|
||||
cmd: Joi.allow('up', 'stop', 'down', 'ps', 'logs'),
|
||||
},
|
||||
},
|
||||
{ allowUnknown: false }
|
||||
),
|
||||
(req, res) => {
|
||||
const { cmd } = req.params
|
||||
const { args } = req.body
|
||||
if (['stop', 'down'].includes(cmd)) {
|
||||
mongoIsInitialized = false
|
||||
}
|
||||
execFile('docker', ['compose', cmd, ...args], (error, stdout, stderr) => {
|
||||
res.json({ error, stdout, stderr })
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
function mongoInit(callback) {
|
||||
execFile(
|
||||
'docker',
|
||||
[
|
||||
'compose',
|
||||
'exec',
|
||||
'mongo',
|
||||
'mongo',
|
||||
'--eval',
|
||||
'rs.initiate({ _id: "overleaf", members: [ { _id: 0, host: "mongo:27017" } ] })',
|
||||
],
|
||||
(error, stdout, stderr) => {
|
||||
if (!error) {
|
||||
mongoIsInitialized = true
|
||||
}
|
||||
callback(error, stdout, stderr)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
app.post('/mongo/init', (req, res) => {
|
||||
mongoInit((error, stdout, stderr) => {
|
||||
res.json({ error, stdout, stderr })
|
||||
})
|
||||
})
|
||||
|
||||
app.post(
|
||||
'/reconfigure',
|
||||
validate(
|
||||
{
|
||||
body: {
|
||||
pro: Joi.boolean().required(),
|
||||
version: Joi.string().required(),
|
||||
vars: allowedVars,
|
||||
},
|
||||
},
|
||||
{ allowUnknown: false }
|
||||
),
|
||||
(req, res) => {
|
||||
const doMongoInit = mongoIsInitialized ? cb => cb() : mongoInit
|
||||
doMongoInit((error, stdout, stderr) => {
|
||||
if (error) return res.json({ error, stdout, stderr })
|
||||
|
||||
const { pro, version, vars } = req.body
|
||||
try {
|
||||
setVersionDockerCompose({ pro, version })
|
||||
setVarsDockerCompose({ vars })
|
||||
} catch (error) {
|
||||
return res.json({ error })
|
||||
}
|
||||
|
||||
execFile(
|
||||
'docker',
|
||||
['compose', 'up', '--detach', '--wait', 'sharelatex'],
|
||||
(error, stdout, stderr) => {
|
||||
res.json({ error, stdout, stderr })
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
app.use(handleValidationErrors())
|
||||
|
||||
// Init on startup
|
||||
mongoInit(err => {
|
||||
if (err) {
|
||||
console.error('mongo init failed', err)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
app.listen(80)
|
||||
})
|
581
server-ce/test/package-lock.json
generated
581
server-ce/test/package-lock.json
generated
|
@ -7,7 +7,11 @@
|
|||
"name": "@overleaf/server-ce/test",
|
||||
"dependencies": {
|
||||
"@testing-library/cypress": "^10.0.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"celebrate": "^15.0.3",
|
||||
"cypress": "13.6.6",
|
||||
"express": "^4.19.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"typescript": "^5.0.4"
|
||||
}
|
||||
},
|
||||
|
@ -221,6 +225,37 @@
|
|||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@hapi/hoek": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
||||
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
|
||||
},
|
||||
"node_modules/@hapi/topo": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
|
||||
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
||||
"integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/formula": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
|
||||
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
|
||||
},
|
||||
"node_modules/@sideway/pinpoint": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
|
||||
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
|
||||
},
|
||||
"node_modules/@testing-library/cypress": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/cypress/-/cypress-10.0.1.tgz",
|
||||
|
@ -288,6 +323,18 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
|
@ -363,6 +410,11 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
|
||||
|
@ -383,6 +435,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
|
@ -491,6 +548,56 @@
|
|||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
|
||||
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.11.0",
|
||||
"raw-body": "2.5.2",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/body-parser/node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
|
@ -531,6 +638,14 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cachedir": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz",
|
||||
|
@ -557,6 +672,16 @@
|
|||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
||||
},
|
||||
"node_modules/celebrate": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/celebrate/-/celebrate-15.0.3.tgz",
|
||||
"integrity": "sha512-ToF8ILq/F0KhQ0CPtexP7Cu9GkqKJ91VKy3ZOCV24aaNWdm3QCHqnXAKfKHrtcM2B2zmPFe11p8WWsQkmq8k4g==",
|
||||
"dependencies": {
|
||||
"escape-html": "1.0.3",
|
||||
"joi": "17.x.x",
|
||||
"lodash": "4.17.x"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
@ -695,6 +820,38 @@
|
|||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
|
@ -880,6 +1037,23 @@
|
|||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/destroy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-accessibility-api": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
|
@ -894,11 +1068,24 @@
|
|||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
|
@ -938,6 +1125,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
|
@ -946,6 +1138,14 @@
|
|||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter2": {
|
||||
"version": "6.4.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
|
||||
|
@ -984,6 +1184,74 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.19.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
|
||||
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.20.2",
|
||||
"content-disposition": "0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.6.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.2.0",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.11.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "0.18.0",
|
||||
"serve-static": "1.15.0",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/express/node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
@ -1038,6 +1306,36 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "2.0.1",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||
|
@ -1067,6 +1365,22 @@
|
|||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
|
@ -1269,6 +1583,21 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||
"dependencies": {
|
||||
"depd": "2.0.0",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"toidentifier": "1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/http-signature": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
|
||||
|
@ -1290,6 +1619,17 @@
|
|||
"node": ">=8.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -1352,6 +1692,14 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||
|
@ -1633,11 +1981,34 @@
|
|||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
|
||||
},
|
||||
"node_modules/joi": {
|
||||
"version": "17.13.1",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz",
|
||||
"integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==",
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.3.0",
|
||||
"@hapi/topo": "^5.1.0",
|
||||
"@sideway/address": "^4.1.5",
|
||||
"@sideway/formula": "^3.0.1",
|
||||
"@sideway/pinpoint": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
|
@ -1802,11 +2173,43 @@
|
|||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
|
@ -1858,6 +2261,14 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||
|
@ -1917,6 +2328,17 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
|
@ -1958,6 +2380,14 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
|
@ -1974,6 +2404,11 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||
},
|
||||
"node_modules/pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
|
@ -2035,6 +2470,18 @@
|
|||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||
"dependencies": {
|
||||
"forwarded": "0.2.0",
|
||||
"ipaddr.js": "1.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
|
||||
|
@ -2081,6 +2528,28 @@
|
|||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
|
@ -2197,6 +2666,61 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.3",
|
||||
"on-finished": "2.4.1",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/debug/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/send/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
|
||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
||||
"dependencies": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
|
||||
|
@ -2224,6 +2748,11 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
|
@ -2298,6 +2827,14 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/stop-iteration-iterator": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
|
||||
|
@ -2373,6 +2910,14 @@
|
|||
"node": ">=8.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
|
@ -2427,6 +2972,18 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"dependencies": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
|
@ -2453,6 +3010,14 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/untildify": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
|
||||
|
@ -2470,6 +3035,14 @@
|
|||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
|
@ -2478,6 +3051,14 @@
|
|||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@testing-library/cypress": "^10.0.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"celebrate": "^15.0.3",
|
||||
"cypress": "13.6.6",
|
||||
"express": "^4.19.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"typescript": "^5.0.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
const { ObjectId } = require('mongodb')
|
||||
const { waitForDb, db } = require('../../../app/src/infrastructure/mongodb')
|
||||
|
||||
waitForDb()
|
||||
.then(async () => {
|
||||
await seedUsers()
|
||||
process.exit(0)
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
const DEFAULT_USER_PROPERTIES = {
|
||||
staffAccess: {
|
||||
publisherMetrics: false,
|
||||
publisherManagement: false,
|
||||
institutionMetrics: false,
|
||||
institutionManagement: false,
|
||||
groupMetrics: false,
|
||||
groupManagement: false,
|
||||
adminMetrics: false,
|
||||
splitTestMetrics: false,
|
||||
splitTestManagement: false,
|
||||
},
|
||||
ace: {
|
||||
mode: 'none',
|
||||
theme: 'textmate',
|
||||
overallTheme: '',
|
||||
fontSize: 12,
|
||||
autoComplete: true,
|
||||
autoPairDelimiters: true,
|
||||
spellCheckLanguage: 'en',
|
||||
pdfViewer: 'pdfjs',
|
||||
syntaxValidation: true,
|
||||
},
|
||||
features: {
|
||||
collaborators: -1,
|
||||
versioning: true,
|
||||
dropbox: true,
|
||||
github: true,
|
||||
gitBridge: true,
|
||||
compileTimeout: 180,
|
||||
compileGroup: 'standard',
|
||||
templates: true,
|
||||
references: true,
|
||||
trackChanges: true,
|
||||
},
|
||||
first_name: 'user',
|
||||
role: '',
|
||||
institution: '',
|
||||
isAdmin: false,
|
||||
lastLoginIp: '',
|
||||
loginCount: 0,
|
||||
holdingAccount: false,
|
||||
must_reconfirm: false,
|
||||
refered_users: [],
|
||||
refered_user_count: 0,
|
||||
alphaProgram: false,
|
||||
betaProgram: false,
|
||||
labsProgram: false,
|
||||
awareOfV2: false,
|
||||
samlIdentifiers: [],
|
||||
thirdPartyIdentifiers: [],
|
||||
|
||||
signUpDate: new Date('2023-11-02T11:36:40.151Z'),
|
||||
featuresOverrides: [],
|
||||
referal_id: 'scTS4kjjJENbfbjG',
|
||||
__v: 0,
|
||||
hashedPassword:
|
||||
'$2a$12$nRvTj6U896uUnE.RFhnGKOyi/CvqBpfxezlqwyIPpezRa2xXLW7MO',
|
||||
}
|
||||
|
||||
async function seedUsers() {
|
||||
const adminUser = {
|
||||
...DEFAULT_USER_PROPERTIES,
|
||||
email: 'admin@example.com',
|
||||
first_name: 'admin',
|
||||
isAdmin: true,
|
||||
emails: [
|
||||
{
|
||||
email: 'admin@example.com',
|
||||
reversedHostname: '',
|
||||
_id: ObjectId('646ca54806d54400b74e77c6'),
|
||||
createdAt: new Date('2023-05-23T11:36:40.494Z'),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const user = {
|
||||
...DEFAULT_USER_PROPERTIES,
|
||||
_id: ObjectId('6543cf90bbe1368944db04d7'),
|
||||
emails: [
|
||||
{
|
||||
email: 'user@example.com',
|
||||
reversedHostname: '',
|
||||
_id: ObjectId('6543c614d58b090b461f3549'),
|
||||
createdAt: new Date('2023-11-21T11:36:40.494Z'),
|
||||
},
|
||||
],
|
||||
email: 'user@example.com',
|
||||
}
|
||||
|
||||
const collaborator = {
|
||||
...DEFAULT_USER_PROPERTIES,
|
||||
_id: ObjectId('6544e78c9b6e937424976b64'),
|
||||
emails: [
|
||||
{
|
||||
email: 'collaborator@example.com',
|
||||
reversedHostname: '',
|
||||
_id: ObjectId('6543c614d58b090b461f354a'),
|
||||
createdAt: new Date('2023-11-21T11:36:40.494Z'),
|
||||
},
|
||||
],
|
||||
email: 'collaborator@example.com',
|
||||
}
|
||||
|
||||
await db.users.insertOne(adminUser)
|
||||
await db.users.insertOne(user)
|
||||
await db.users.insertOne(collaborator)
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "Seeding mongo for e2e tests"
|
||||
cd /overleaf/services/web
|
||||
node modules/server-ce-scripts/scripts/seed-mongo
|
||||
node modules/server-ce-scripts/scripts/check-redis
|
||||
echo "mongo seeding complete"
|
Loading…
Reference in a new issue