Compare commits

...

6 Commits

Author SHA1 Message Date
Elias Schneider
6b39adfd03 release: 1.1.1 2024-09-18 23:32:52 +02:00
Elias Schneider
d9cfe697d6 fix: disable email login if ldap is enabled 2024-09-18 23:32:09 +02:00
Elias Schneider
67a0fc6ea5 docs: improve ClamAV docs 2024-09-18 23:16:41 +02:00
Elias Schneider
b13a81a88c feat: add environment variable to trust the reverse proxy 2024-09-18 23:01:50 +02:00
Elias Schneider
97dc3ecfdd chore(docs): dump dependencies 2024-09-18 11:08:05 +02:00
Elias Schneider
d00d52baa9 chore: dump dependencies 2024-09-18 11:04:06 +02:00
23 changed files with 3271 additions and 2959 deletions

View File

@@ -1,3 +1,15 @@
## [1.1.1](https://github.com/stonith404/pingvin-share/compare/v1.1.0...v1.1.1) (2024-09-18)
### Features
* add environment variable to trust the reverse proxy ([b13a81a](https://github.com/stonith404/pingvin-share/commit/b13a81a88ca871c5714b2ed52d0e12fb7ceca176))
### Bug Fixes
* disable email login if ldap is enabled ([d9cfe69](https://github.com/stonith404/pingvin-share/commit/d9cfe697d66e9db7bfbc2252b3700580793ce9bb))
## [1.1.0](https://github.com/stonith404/pingvin-share/compare/v1.0.4...v1.1.0) (2024-09-14)

View File

@@ -1,15 +0,0 @@
:3000 {
# Reverse proxy for /api
reverse_proxy /api/* http://localhost:8080 {
header_up X-Forwarded-Host {host}:{server_port}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# Reverse proxy for all other requests
reverse_proxy http://localhost:3333 {
header_up X-Forwarded-Host {host}:{server_port}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}

View File

@@ -46,7 +46,7 @@ COPY --from=backend-builder /opt/app/dist ./dist
COPY --from=backend-builder /opt/app/prisma ./prisma
COPY --from=backend-builder /opt/app/package.json ./
COPY ./Caddyfile /etc/caddy/Caddyfile
COPY ./reverse-proxy /etc/caddy
COPY ./scripts/docker-entrypoint.sh /opt/app/docker-entrypoint.sh
WORKDIR /opt/app

2045
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "pingvin-share-backend",
"version": "1.1.0",
"version": "1.1.1",
"scripts": {
"build": "nest build",
"dev": "cross-env NODE_ENV=development nest start --watch",
@@ -14,23 +14,23 @@
},
"dependencies": {
"@nestjs/cache-manager": "^2.2.2",
"@nestjs/common": "^10.3.9",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.3.9",
"@nestjs/common": "^10.4.3",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.4.3",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.9",
"@nestjs/schedule": "^4.0.2",
"@nestjs/swagger": "^7.3.1",
"@nestjs/throttler": "^5.2.0",
"@prisma/client": "^5.16.1",
"@nestjs/platform-express": "^10.4.3",
"@nestjs/schedule": "^4.1.1",
"@nestjs/swagger": "^7.4.2",
"@nestjs/throttler": "^6.2.1",
"@prisma/client": "^5.19.1",
"@types/jmespath": "^0.15.2",
"@types/ldapjs": "^3.0.6",
"archiver": "^7.0.1",
"argon2": "^0.40.3",
"body-parser": "^1.20.2",
"cache-manager": "^5.6.1",
"clamscan": "^2.2.1",
"argon2": "^0.41.1",
"body-parser": "^1.20.3",
"cache-manager": "^5.7.6",
"clamscan": "^2.3.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"content-disposition": "^0.5.4",
@@ -40,48 +40,48 @@
"mime-types": "^2.1.35",
"moment": "^2.30.1",
"nanoid": "^3.3.7",
"nodemailer": "^6.9.14",
"nodemailer": "^6.9.15",
"otplib": "^12.0.1",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"qrcode-svg": "^1.1.0",
"reflect-metadata": "^0.2.2",
"rimraf": "^5.0.7",
"rimraf": "^6.0.1",
"rxjs": "^7.8.1",
"sharp": "^0.33.4",
"sharp": "^0.33.5",
"ts-node": "^10.9.2"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.9",
"@nestjs/cli": "^10.4.5",
"@nestjs/schematics": "^10.1.4",
"@nestjs/testing": "^10.4.3",
"@types/archiver": "^6.0.2",
"@types/clamscan": "^2.0.8",
"@types/cookie-parser": "^1.4.7",
"@types/cron": "^2.0.1",
"@types/cron": "^2.4.0",
"@types/express": "^4.17.21",
"@types/mime-types": "^2.1.4",
"@types/multer": "^1.4.11",
"@types/node": "^20.14.9",
"@types/nodemailer": "^6.4.15",
"@types/multer": "^1.4.12",
"@types/node": "^22.5.5",
"@types/nodemailer": "^6.4.16",
"@types/passport-jwt": "^4.0.1",
"@types/qrcode-svg": "^1.1.4",
"@types/sharp": "^0.31.1",
"@types/qrcode-svg": "^1.1.5",
"@types/sharp": "^0.32.0",
"@types/supertest": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@typescript-eslint/eslint-plugin": "^8.6.0",
"@typescript-eslint/parser": "^8.6.0",
"cross-env": "^7.0.3",
"eslint": "^8.56.0",
"eslint": "^9.10.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"newman": "^6.1.3",
"prettier": "^3.3.2",
"prisma": "^5.16.1",
"eslint-plugin-prettier": "^5.2.1",
"newman": "^6.2.1",
"prettier": "^3.3.3",
"prisma": "^5.19.1",
"source-map-support": "^0.5.21",
"ts-loader": "^9.5.1",
"tsconfig-paths": "4.2.0",
"typescript": "^5.5.2",
"wait-on": "^7.2.0"
"typescript": "^5.6.2",
"wait-on": "^8.0.1"
}
}

View File

@@ -4,15 +4,11 @@ services:
restart: unless-stopped
ports:
- 3000:3000
environment:
- TRUST_PROXY=false # Set to true if a reverse proxy is in front of the container
volumes:
- "./data:/opt/app/backend/data"
- "./data/images:/opt/app/frontend/public/img"
# Optional: If you add ClamAV, uncomment the following to have ClamAV start first.
# depends_on:
# clamav:
# condition: service_healthy
# Optional: Add ClamAV (see README.md)
# ClamAV is currently only available for AMD64 see https://github.com/Cisco-Talos/clamav/issues/482
# clamav:
# restart: unless-stopped
# image: clamav/clamav
# To add ClamAV, to scan your shares for malicious files,
# see https://stonith404.github.io/pingvin-share/setup/integrations/#clamav-docker-only

View File

@@ -48,3 +48,9 @@ For installation specific configuration, you can use environment variables. The
| --------- | ----------------------- | ---------------------------------------- |
| `PORT` | `3000` | The port on which the frontend listens. |
| `API_URL` | `http://localhost:8080` | The URL of the backend for the frontend. |
#### Reverse Proxy (inside the Docker container)
| Variable | Default Value | Description |
| ------------- | ------------- | ----------------------------------------------------------------------------------------------------------- |
| `TRUST_PROXY` | `false` | Whether Pingvin Share is behind a reverse proxy. If set to `true`, the `X-Forwarded-For` header is trusted. |

View File

@@ -40,6 +40,6 @@ API_URL=http://localhost:8080 # Set the URL of the backend, default: http://loca
pm2 start --name="pingvin-share-frontend" .next/standalone/server.js
```
**Uploading Large Files**: By default, Pingvin Share uses a built-in reverse proxy to reduce the installation steps. However, this reverse proxy is not optimized for uploading large files. If you wish to upload larger files, you can either use the Docker installation or set up your own reverse proxy. An example configuration for Caddy can be found in `./Caddyfile`.
**Uploading Large Files**: By default, Pingvin Share uses a built-in reverse proxy to reduce the installation steps. However, this reverse proxy is not optimized for uploading large files. If you wish to upload larger files, you can either use the Docker installation or set up your own reverse proxy. An example configuration for Caddy can be found in `./reverse-proxy/Caddyfile`.
The website is now listening on `http://localhost:3000`, have fun with Pingvin Share 🐧!

View File

@@ -4,11 +4,29 @@ id: integrations
# Integrations
#### ClamAV (Docker only)
#### ClamAV
> **_NOTE:_** Currently ClamAV is only available in the Docker installation.
ClamAV is used to scan shares for malicious files and remove them if found.
1. Add the ClamAV container to the Docker Compose stack (see `docker-compose.yml`) and start the container.
1. Add the ClamAV container to the Docker Compose stack and start the container.
```diff
services:
pingvin-share:
image: stonith404/pingvin-share
...
+ depends_on:
+ clamav:
+ condition: service_healthy
+ clamav:
+ restart: unless-stopped
+ image: clamav/clamav
```
2. Docker will wait for ClamAV to start before starting Pingvin Share. This may take a minute or two.
3. The Pingvin Share logs should now log "ClamAV is active"

828
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"deploy": "GIT_USER=stonith404 docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
@@ -15,19 +15,19 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "3.4.0",
"@docusaurus/preset-classic": "3.4.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
"@docusaurus/core": "3.5.2",
"@docusaurus/preset-classic": "3.5.2",
"@mdx-js/react": "^3.0.1",
"clsx": "^2.1.1",
"prism-react-renderer": "^2.4.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.4.0",
"@docusaurus/tsconfig": "3.4.0",
"@docusaurus/types": "3.4.0",
"typescript": "~5.2.2"
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/tsconfig": "3.5.2",
"@docusaurus/types": "3.5.2",
"typescript": "~5.6.2"
},
"browserslist": {
"production": [

View File

@@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "pingvin-share-frontend",
"version": "1.1.0",
"version": "1.1.1",
"scripts": {
"dev": "next dev",
"build": "next build",
@@ -9,7 +9,7 @@
"format": "prettier --end-of-line=auto --write \"src/**/*.ts*\""
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/react": "^11.13.3",
"@emotion/server": "^11.11.0",
"@mantine/core": "^6.0.21",
"@mantine/dropzone": "^6.0.21",
@@ -18,37 +18,37 @@
"@mantine/modals": "^6.0.21",
"@mantine/next": "^6.0.21",
"@mantine/notifications": "^6.0.21",
"axios": "^1.7.2",
"cookies-next": "^2.1.2",
"axios": "^1.7.7",
"cookies-next": "^4.2.1",
"file-saver": "^2.0.5",
"jose": "^4.15.5",
"jwt-decode": "^3.1.2",
"markdown-to-jsx": "^7.4.7",
"jose": "^5.9.2",
"jwt-decode": "^4.0.0",
"markdown-to-jsx": "^7.5.0",
"mime-types": "^2.1.35",
"moment": "^2.30.1",
"next": "^14.2.3",
"next": "^14.2.12",
"next-http-proxy-middleware": "^1.2.6",
"next-pwa": "^5.6.0",
"p-limit": "^4.0.0",
"p-limit": "^6.1.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^4.12.0",
"react-icons": "^5.3.0",
"react-intl": "^6.6.8",
"sharp": "^0.33.4",
"sharp": "^0.33.5",
"yup": "^1.4.0"
},
"devDependencies": {
"@types/mime-types": "^2.1.4",
"@types/node": "20.12.12",
"@types/react": "18.3.2",
"@types/node": "22.5.5",
"@types/react": "18.3.7",
"@types/react-dom": "18.3.0",
"@typescript-eslint/parser": "^7.10.0",
"axios": "^1.7.2",
"@typescript-eslint/parser": "^8.6.0",
"axios": "^1.7.7",
"eslint": "8.57.0",
"eslint-config-next": "^13.5.6",
"eslint-config-prettier": "^8.10.0",
"prettier": "^3.2.5",
"tar": "^6.2.1",
"typescript": "^5.4.5"
"eslint-config-next": "^14.2.12",
"eslint-config-prettier": "^9.1.0",
"prettier": "^3.3.3",
"tar": "^7.4.3",
"typescript": "^5.6.2"
}
}

View File

@@ -80,7 +80,9 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => {
useState(false);
const validationSchema = yup.object().shape({
emailOrUsername: yup.string().required(t("common.error.field-required")),
emailOrUsername: config.get("ldap.enabled")
? yup.string().matches(/^[^@]+$/, t("signIn.error.invalid-username"))
: yup.string().required(t("common.error.field-required")),
password: yup
.string()
.min(8, t("common.error.too-short", { length: 8 }))
@@ -172,8 +174,16 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => {
})}
>
<TextInput
label={t("signin.input.email-or-username")}
placeholder={t("signin.input.email-or-username.placeholder")}
label={
config.get("ldap.enabled")
? t("signup.input.username")
: t("signin.input.email-or-username")
}
placeholder={
config.get("ldap.enabled")
? t("signup.input.username.placeholder")
: t("signin.input.email-or-username.placeholder")
}
{...form.getInputProps("emailOrUsername")}
/>
<PasswordInput

View File

@@ -50,6 +50,7 @@ export default {
"signIn.oauth.microsoft": "Microsoft",
"signIn.oauth.discord": "Discord",
"signIn.oauth.oidc": "OpenID",
"signIn.error.invalid-username": "Invalid username",
// END /auth/signin

View File

@@ -1,4 +1,4 @@
import jwtDecode from "jwt-decode";
import { jwtDecode } from "jwt-decode";
import { NextRequest, NextResponse } from "next/server";
import configService from "./services/config.service";

View File

@@ -14,7 +14,7 @@ import {
import { useForm, yupResolver } from "@mantine/form";
import { useModals } from "@mantine/modals";
import { useEffect, useState } from "react";
import { Tb2Fa } from "react-icons/tb";
import { TbAuth2Fa } from "react-icons/tb";
import { FormattedMessage } from "react-intl";
import * as yup from "yup";
import Meta from "../../components/Meta";
@@ -293,7 +293,7 @@ const Account = () => {
<Tabs defaultValue="totp">
<Tabs.List>
<Tabs.Tab value="totp" icon={<Tb2Fa size={14} />}>
<Tabs.Tab value="totp" icon={<TbAuth2Fa size={14} />}>
TOTP
</Tabs.Tab>
</Tabs.List>

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "pingvin-share",
"version": "1.1.0",
"version": "1.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pingvin-share",
"version": "1.1.0",
"version": "1.1.1",
"devDependencies": {
"conventional-changelog-cli": "^3.0.0"
}

View File

@@ -1,6 +1,6 @@
{
"name": "pingvin-share",
"version": "1.1.0",
"version": "1.1.1",
"scripts": {
"format": "cd frontend && npm run format && cd ../backend && npm run format",
"lint": "cd frontend && npm run lint && cd ../backend && npm run lint",

7
reverse-proxy/Caddyfile Normal file
View File

@@ -0,0 +1,7 @@
:3000 {
# Reverse proxy for /api
reverse_proxy /api/* http://localhost:8080
# Reverse proxy for all other requests
reverse_proxy http://localhost:3333
}

View File

@@ -0,0 +1,14 @@
:3000 {
reverse_proxy /* http://localhost:3333 {
trusted_proxies 0.0.0.0/0
}
reverse_proxy /api/* http://localhost:8080 {
trusted_proxies 0.0.0.0/0
}
log {
output file /var/log/caddy/access.log
level WARN
}
}

View File

@@ -4,10 +4,17 @@
cp -rn /tmp/img/* /opt/app/frontend/public/img
# Start Caddy
caddy start --config /etc/caddy/Caddyfile &
if [ "$TRUST_PROXY" = "true" ]; then
caddy start --config /etc/caddy/Caddyfile.trust-proxy &
else
caddy start --config /etc/caddy/Caddyfile &
fi
# Run the frontend server
PORT=3333 HOSTNAME=0.0.0.0 node frontend/server.js &
# Run the backend server
cd backend && npm run prod
# Wait for all processes to finish
wait -n