Compare commits

..

1 commit

Author SHA1 Message Date
52761e409f Update dependency ejs to v3.1.10
All checks were successful
ci / build-image (pull_request) Successful in 3m32s
2025-06-12 22:05:26 +00:00
9 changed files with 171 additions and 195 deletions

View file

@ -1,25 +0,0 @@
export DEBUG="hostr*"
export NODE_ENV=development
export PORT=4040
export WEB_BASE_URL=http://localhost:$PORT
export API_BASE_URL=$WEB_BASE_URL/api
export UPLOAD_STORAGE_PATH=$HOME/.hostr/uploads
export COOKIE_KEY=INSECURE
export EMAIL_FROM=
export EMAIL_NAME=
export STATSD_HOST=localhost
export DATABASE_URL=postgresql://hostr:hostr@database:5432/hostr
export REDIS_URL=redis://localhost:6379
export SENDGRID_KEY=
export STRIPE_SECRET_KEY=
export STRIPE_PUBLIC_KEY=
# optional, some functionality will be disabled
export AWS_ENDPOINT= # only for AWS-like providers, not AWS
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_BUCKET=
export VIRUSTOTAL_KEY=
export SENTRY_DSN=

View file

@ -1,12 +0,0 @@
WEB_BASE_URL=http://localhost:3000
API_BASE_URL=http://localhost:3000/api
UPLOAD_STORAGE_PATH=/hostr/uploads
COOKIE_KEY=TESTING
EMAIL_FROM=jonathan@hostr.co
EMAIL_NAME="Jonathan from Hostr"
DATABASE_URL=postgresql://hostr:hostr@database:5432/hostr
REDIS_URL=redis://redis:6379
AWS_ENDPOINT=http://minio:9000
AWS_ACCESS_KEY_ID=7HYV3KPRGQ8Z5YCDNWC6
AWS_SECRET_ACCESS_KEY=0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/
AWS_BUCKET=hostr

View file

@ -0,0 +1,40 @@
name: ci
on:
push:
branches: main
pull_request:
types: [opened, synchronize, reopened]
jobs:
build-image:
runs-on: self-hosted
steps:
- name: Set current date as env variable
run: echo "NOW=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_ENV
- name: Fix for bad os check
run: echo "RUNNER_OS=Linux" >> $GITHUB_ENV
- name: Login to Forgejo Registry
uses: https://cremin.dev/actions/podman-login@v1
with:
registry: cremin.dev
username: ${{ github.actor }}
password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
- name: Check out repository
uses: https://cremin.dev/actions/checkout@v4
- name: Build image
uses: https://cremin.dev/actions/buildah-build@v2
with:
containerfiles: ./Containerfile
context: ./
oci: true
layers: true
image: hostr
tags: latest ${{ github.sha }}
- name: Push image
uses: https://cremin.dev/actions/push-to-registry@v2
with:
registry: cremin.dev/jonathan
username: ${{ github.actor }}
password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
image: hostr
tags: latest ${{ github.sha }}

View file

@ -1,57 +0,0 @@
name: ci
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened]
jobs:
build-image:
runs-on: self-hosted
steps:
- name: Set current date as env variable
run: echo "NOW=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_ENV
- name: Fix for bad os check
run: echo "RUNNER_OS=Linux" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: https://cremin.dev/actions/docker-login@v3
with:
registry: cremin.dev
username: ${{ github.actor }}
password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
- name: Check out repository
uses: https://cremin.dev/actions/checkout@v4
- name: Set up Docker Buildx
uses: https://cremin.dev/actions/docker-setup-buildx@v3
- name: Build and push
uses: https://cremin.dev/actions/docker-build-push@v6
with:
file: ./Containerfile
context: ./
tags: cremin.dev/jonathan/hostr:latest,cremin.dev/jonathan/hostr:${{ github.sha }}
push: true
test-image:
runs-on: node22
needs: build-image
services:
database:
image: postgres:14-alpine
env:
POSTGRES_PASSWORD: hostr
POSTGRES_USER: hostr
POSTGRES_DB: hostr
redis:
image: redis:4.0.2-alpine
minio:
image: minio/minio
env:
MINIO_ACCESS_KEY: 7HYV3KPRGQ8Z5YCDNWC6
MINIO_SECRET_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/
cmd: ["server", "/export"]
steps:
- name: Check out repository
uses: https://cremin.dev/actions/checkout@v4
- name: Test image
run: |
docker run --env-file ./.forgejo/workflows/.env --rm -it cremin.dev/jonathan/hostr:${{ github.sha }} yarn test

3
.gitignore vendored
View file

@ -1,4 +1,4 @@
.envrc
.env*
.DS_Store
.sass-cache/
node_modules
@ -7,7 +7,6 @@ jspm_packages
npm-debug.log
web/public/build
web/public/styles/*.css
web/public/styles/*.css.map
*.gz
minigun*.json
test*.json

View file

@ -10,36 +10,36 @@ help:
.PHONY: build
build: ## Run `yarn run build`
podman compose run --rm app yarn run build
docker-compose run --rm app yarn run build
.PHONY: test
test: ## Run tests
podman compose run --rm app yarn test
docker-compose run --rm app yarn test
.PHONY: logs
logs: ## Tail the app and worker logs
podman compose logs -f app worker
docker-compose logs -f app worker
.PHONY: migrate
migrate: ## Migrate database schema
podman compose run --rm app yarn run initdb
docker-compose run --rm app yarn run initdb
.PHONY: init
init: ## Migrate database schema
podman compose run --rm app yarn run init
docker-compose run --rm app yarn run init
.PHONY: watch-frontend
watch-frontend: ## Build and watch for changes
podman compose run --rm app yarn run watch
docker-compose run --rm app yarn run watch
.PHONY: podman compose-up
podman compose-up: ## Start (and create) docker containers
podman compose up -d
.PHONY: docker-compose-up
docker-compose-up: ## Start (and create) docker containers
docker-compose up -d
.PHONY: yarn
yarn: ## Update yarn dependencies
podman compose run --rm app yarn
docker-compose run --rm app yarn
.PHONY: shell
shell: ## Run shell
podman compose run --rm app sh
docker-compose run --rm app sh

View file

@ -61,7 +61,7 @@ services:
- "3001:3000"
command: yarn run worker
database:
image: "postgres:14-alpine"
image: "postgres:10-alpine"
ports:
- "5432:5432"
environment:
@ -69,7 +69,7 @@ services:
POSTGRES_USER: "hostr"
POSTGRES_DB: "hostr"
redis:
image: "redis:8-alpine"
image: "redis:4.0.2-alpine"
ports:
- "6379:6379"
minio:

View file

@ -1,29 +1,29 @@
import crypto from "crypto";
import { join } from "path";
import passwords from "passwords";
import uuid from "node-uuid";
import views from "co-views";
import debugname from "debug";
import sendgrid from "@sendgrid/mail";
import models from "../../models";
import crypto from 'crypto';
import { join } from 'path';
import passwords from 'passwords';
import uuid from 'node-uuid';
import views from 'co-views';
import debugname from 'debug';
import sendgrid from '@sendgrid/mail';
import models from '../../models';
const render = views(join(__dirname, "..", "views"), { default: "ejs" });
const debug = debugname("hostr-web:auth");
const render = views(join(__dirname, '..', 'views'), { default: 'ejs' });
const debug = debugname('hostr-web:auth');
sendgrid.setApiKey(process.env.SENDGRID_KEY);
const from = process.env.EMAIL_FROM;
const fromname = process.env.EMAIL_NAME;
export async function authenticate(email, password) {
const remoteIp = this.headers["x-forwarded-for"] || this.ip;
const remoteIp = this.headers['x-forwarded-for'] || this.ip;
if (!password || password.length < 6) {
debug("No password, or password too short");
return new Error("Invalid login details");
debug('No password, or password too short');
return new Error('Invalid login details');
}
const count = await models.login.count({
where: {
ip: remoteIp.split(",")[0],
ip: remoteIp.split(',')[0],
successful: false,
createdAt: {
$gt: Math.ceil(Date.now()) - 600000,
@ -32,8 +32,8 @@ export async function authenticate(email, password) {
});
if (count > 25) {
debug("Throttling brute force");
return new Error("Invalid login details");
debug('Throttling brute force');
return new Error('Invalid login details');
}
const user = await models.user.findOne({
where: {
@ -43,29 +43,30 @@ export async function authenticate(email, password) {
});
const login = await models.login.create({
ip: remoteIp.split(",")[0],
ip: remoteIp.split(',')[0],
successful: false,
});
if (user && user.password) {
login.userId = user.id;
if (await passwords.verify(password, user.password)) {
debug("Password verified");
debug('Password verified');
login.successful = true;
await login.save();
return user;
}
debug("Password invalid");
debug('Password invalid');
}
await login.save();
return false;
}
export async function setupSession(user) {
debug("Setting up session");
const token = uuid.v4();
await this.redis.set(token, user.id, "EX", 604800);
export async function setupSession(user) {
debug('Setting up session');
const token = uuid.v4();
debug(user)
await this.redis.set(token, user.id, 'EX', 604800);
const sessionUser = {
id: user.id,
@ -75,26 +76,27 @@ export async function setupSession(user) {
joined: user.createdAt,
plan: user.plan,
uploadsToday: await models.file.count({ userId: user.id }),
md5: crypto.createHash("md5").update(user.email).digest("hex"),
md5: crypto.createHash('md5').update(user.email).digest('hex'),
token,
};
if (sessionUser.plan === "Pro") {
if (sessionUser.plan === 'Pro') {
sessionUser.maxFileSize = 524288000;
sessionUser.dailyUploadAllowance = "unlimited";
sessionUser.dailyUploadAllowance = 'unlimited';
}
this.session.user = sessionUser;
if (this.request.body.remember && this.request.body.remember === "on") {
if (this.request.body.remember && this.request.body.remember === 'on') {
const remember = await models.remember.create({
id: uuid(),
userId: user.id,
});
this.cookies.set("r", remember.id, { maxAge: 1209600000, httpOnly: true });
this.cookies.set('r', remember.id, { maxAge: 1209600000, httpOnly: true });
}
debug("Session set up");
debug('Session set up');
}
export async function signup(email, password, ip) {
const existingUser = await models.user.findOne({
where: {
@ -103,29 +105,26 @@ export async function signup(email, password, ip) {
},
});
if (existingUser) {
debug("Email already in use.");
throw new Error("Email already in use.");
debug('Email already in use.');
throw new Error('Email already in use.');
}
const cryptedPassword = await passwords.crypt(password);
const user = await models.user.create(
{
const user = await models.user.create({
email,
password: cryptedPassword,
ip,
plan: 'Free',
activation: {
id: uuid(),
email,
password: cryptedPassword,
ip,
plan: "Free",
activation: {
id: uuid(),
email,
},
},
{
include: [models.activation],
},
);
}, {
include: [models.activation],
});
await user.save();
const html = await render("email/inlined/activate", {
const html = await render('email/inlined/activate', {
activationUrl: `${process.env.WEB_BASE_URL}/activate/${user.activation.id}`,
});
const text = `Thanks for signing up to Hostr!
@ -137,15 +136,18 @@ ${process.env.WEB_BASE_URL}/activate/${user.activation.id}
`;
sendgrid.send({
to: user.email,
subject: "Welcome to Hostr",
subject: 'Welcome to Hostr',
from,
fromname,
html,
text,
categories: ["activate"],
categories: [
'activate',
],
});
}
export async function sendResetToken(email) {
const user = await models.user.findOne({
where: {
@ -157,7 +159,7 @@ export async function sendResetToken(email) {
id: uuid.v4(),
userId: user.id,
});
const html = await render("email/inlined/forgot", {
const html = await render('email/inlined/forgot', {
forgotUrl: `${process.env.WEB_BASE_URL}/forgot/${reset.id}`,
});
const text = `It seems you've forgotten your password :(
@ -165,32 +167,38 @@ Visit ${process.env.WEB_BASE_URL}/forgot/${reset.id} to set a new one.
`;
sendgrid.send({
to: user.email,
from: "jonathan@hostr.co",
fromname: "Jonathan from Hostr",
subject: "Hostr Password Reset",
from: 'jonathan@hostr.co',
fromname: 'Jonathan from Hostr',
subject: 'Hostr Password Reset',
html,
text,
categories: ["password-reset"],
categories: [
'password-reset',
],
});
} else {
throw new Error("There was an error looking up your email address.");
throw new Error('There was an error looking up your email address.');
}
}
export async function fromToken(token) {
const userId = await this.redis.get(token);
return models.user.findByPk(userId);
}
export async function fromCookie(rememberId) {
const userId = await models.remember.findByPk(rememberId);
return models.user.findByPk(userId);
}
export async function validateResetToken(resetId) {
return models.reset.findByPk(resetId);
}
export async function updatePassword(userId, password) {
const cryptedPassword = await passwords.crypt(password);
const user = await models.user.findByPk(userId);
@ -198,6 +206,7 @@ export async function updatePassword(userId, password) {
await user.save();
}
export async function activateUser(code) {
const activation = await models.activation.findOne({
where: {

View file

@ -1148,10 +1148,10 @@ async-each@^1.0.0, async-each@^1.0.1:
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
async@0.9.x:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
async@^3.2.3:
version "3.2.6"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
asynckit@^0.4.0:
version "0.4.0"
@ -1402,9 +1402,9 @@ backo@~1.0.1:
integrity sha1-2Gzk/CpQzf9rnTqXrNXJZA3k2Sc=
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.0.2:
version "1.3.1"
@ -1495,13 +1495,20 @@ bowser@2.9.0:
integrity sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
version "1.1.12"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
dependencies:
balanced-match "^1.0.0"
braces@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
@ -1800,6 +1807,14 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
character-parser@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
@ -2068,7 +2083,7 @@ color-convert@^2.0.1:
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4:
version "1.1.4"
@ -2107,7 +2122,7 @@ compressible@^2.0.0:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
concat-stream@^1.5.0:
version "1.6.2"
@ -2711,11 +2726,11 @@ ejs@3.0.1:
integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw==
ejs@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.3.tgz#514d967a8894084d18d3d47bd169a1c0560f093d"
integrity sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==
version "3.1.10"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==
dependencies:
jake "^10.6.1"
jake "^10.8.5"
elliptic@^6.0.0:
version "6.5.2"
@ -2858,7 +2873,7 @@ escape-html@^1.0.3, escape-html@~1.0.3:
escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
eslint-config-airbnb-base@^14.1.0:
version "14.2.0"
@ -3329,12 +3344,12 @@ file-uri-to-path@1.0.0:
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
filelist@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb"
integrity sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==
filelist@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
dependencies:
minimatch "^3.0.4"
minimatch "^5.0.1"
filename-regex@^2.0.0:
version "2.0.1"
@ -3804,7 +3819,7 @@ has-ansi@^2.0.0:
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
has-flag@^4.0.0:
version "4.0.0"
@ -4573,15 +4588,15 @@ iterate-value@^1.0.0:
es-get-iterator "^1.0.2"
iterate-iterator "^1.0.1"
jake@^10.6.1:
version "10.8.1"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.1.tgz#0f6f5ef13ebe014104527fb4b1b24f44cd1f04d6"
integrity sha512-eSp5h9S7UFzKdQERTyF+KuPLjDZa1Tbw8gCVUn98n4PbIkLEDGe4zl7vF4Qge9kQj06HcymnksPk8jznPZeKsA==
jake@^10.8.5:
version "10.9.2"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f"
integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==
dependencies:
async "0.9.x"
chalk "^2.4.2"
filelist "^1.0.1"
minimatch "^3.0.4"
async "^3.2.3"
chalk "^4.0.2"
filelist "^1.0.4"
minimatch "^3.1.2"
jimp@^0.13.0:
version "0.13.0"
@ -5326,20 +5341,27 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4:
minimatch@3.0.4, minimatch@^3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
minimatch@^3.1.2:
minimatch@^3.0.4, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"