Compare commits
5 Commits
d7fa763d5e
...
ab57acdcd1
Author | SHA1 | Date | |
---|---|---|---|
ab57acdcd1 | |||
26609ebd6b | |||
d21291c643 | |||
4c9a868d6b | |||
c68141575f |
@ -26,9 +26,12 @@ Aplikace sestává ze dvou (tří) modulů.
|
||||
- [Docker](https://www.docker.com)
|
||||
- [Docker Compose](https://docs.docker.com/compose)
|
||||
|
||||
### Spuštění
|
||||
### Spuštění s nginx
|
||||
- `docker compose up --build -d`
|
||||
|
||||
### Spuštení s traefik
|
||||
- `docker compose -f compose-traefik.yml up --build -d`
|
||||
|
||||
## TODO
|
||||
- [x] Umožnit smazání aktuální volby "popelnicí", místo nutnosti vybrat prázdnou položku v selectu
|
||||
- [x] Přívětivější možnost odhlašování
|
||||
|
@ -18,6 +18,6 @@ ENV NODE_ENV production
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /build .
|
||||
|
||||
EXPOSE 3000
|
||||
RUN yarn global add serve && yarn
|
||||
CMD ["serve", "-s", "."]
|
@ -22,8 +22,8 @@ const api = {
|
||||
post: <TBody extends BodyInit, TResponse>(url: string, body: TBody) => request<TResponse>(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json' } }),
|
||||
}
|
||||
|
||||
export const getQrUrl = () => {
|
||||
return `${getBaseUrl()}/api/qr`;
|
||||
export const getQrUrl = (login: string) => {
|
||||
return `${getBaseUrl()}/api/qr?login=${login}`;
|
||||
}
|
||||
|
||||
export const getData = async () => {
|
||||
|
@ -353,7 +353,7 @@ function App() {
|
||||
<div className='qr-code'>
|
||||
<h3>QR platba</h3>
|
||||
<div>Částka: {myOrder.totalPrice} Kč</div>
|
||||
<img src={getQrUrl()} alt='QR kód' />
|
||||
<img src={getQrUrl(auth.login)} alt='QR kód' />
|
||||
<p>Generování QR kódů je v experimentální fázi - doporučujeme si překontrolovat údaje před odesláním platby.</p>
|
||||
</div>
|
||||
}
|
||||
|
51
compose-traefik.yml
Normal file
51
compose-traefik.yml
Normal file
@ -0,0 +1,51 @@
|
||||
version: "3"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
name: traefik_proxy
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:latest"
|
||||
container_name: "traefik"
|
||||
command:
|
||||
# - "--log.level=DEBUG"
|
||||
#- "--log.filePath=/log/traefik.log"
|
||||
- "--accesslog=true"
|
||||
#- "--accessLog.filePath=/log/access.log"
|
||||
- "--api.insecure=false" # pokud chci dashboard
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
#- "--entryPoints.websecure.address=:443"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
ports:
|
||||
- "${HTTP_PORT:-80}:80"
|
||||
#- "443:443"
|
||||
volumes:
|
||||
#- "./traefik/log:/log"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
- "/etc/timezone:/etc/timezone:ro"
|
||||
environment:
|
||||
- "TZ=Europe/Prague"
|
||||
server:
|
||||
build:
|
||||
context: ./server
|
||||
networks:
|
||||
- proxy
|
||||
labels:
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.http.routers.server.rule=Host(`${DOMAIN:-localhost}`) && (PathPrefix(`/socket.io`) || PathPrefix(`/api`))'
|
||||
client:
|
||||
build:
|
||||
context: ./client
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
- proxy
|
||||
labels:
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.http.routers.client.rule=Host(`${DOMAIN:-localhost}`)'
|
||||
|
@ -13,4 +13,6 @@ COPY src ./src
|
||||
RUN yarn install --frozen-lockfile
|
||||
RUN yarn build
|
||||
|
||||
EXPOSE 3001
|
||||
|
||||
CMD [ "node", "/app/dist/index.js" ]
|
@ -6,13 +6,16 @@ import jwt from 'jsonwebtoken';
|
||||
* @param login přihlašovací jméno uživatele
|
||||
* @returns JWT token
|
||||
*/
|
||||
export function generateToken(login: string): string {
|
||||
export function generateToken(login?: string): string {
|
||||
if (!process.env.JWT_SECRET) {
|
||||
throw Error("Není vyplněna proměnná prostředí JWT_SECRET");
|
||||
}
|
||||
if (process.env.JWT_SECRET.length < 32) {
|
||||
throw Error("Proměnná prostředí JWT_SECRET musí být minimálně 32 znaků");
|
||||
}
|
||||
if (!login || login.trim().length === 0) {
|
||||
throw Error("Nebyl předán login");
|
||||
}
|
||||
return jwt.sign({ login }, process.env.JWT_SECRET);
|
||||
}
|
||||
|
||||
|
@ -43,17 +43,32 @@ app.get("/api/whoami",(req,res)=>{
|
||||
})
|
||||
|
||||
app.post("/api/login", (req, res) => {
|
||||
if (!req.body?.login) {
|
||||
// Autentizace pomocí trusted headers
|
||||
const remoteUser = req.header('remote-user');
|
||||
if (remoteUser && remoteUser.length > 0) {
|
||||
res.status(200).json(generateToken(remoteUser));
|
||||
return;
|
||||
}
|
||||
// Klasická autentizace loginem
|
||||
if (!req.body?.login || req.body.login.trim().length === 0) {
|
||||
throw Error("Nebyl předán login");
|
||||
}
|
||||
// TODO: je tohle hnusny?... bude to fungovat? lol
|
||||
if (req.header('remote-user')){
|
||||
let username = req.header('remote-user') || "jmenonemahlavicku"
|
||||
res.status(200).json(generateToken(username));
|
||||
} else {
|
||||
// TODO zavést podmínky pro délku loginu (min i max)
|
||||
res.status(200).json(generateToken(req.body.login));
|
||||
});
|
||||
|
||||
// TODO dočasné řešení - QR se zobrazuje přes <img>, nemáme sem jak dostat token
|
||||
app.get("/api/qr", (req, res) => {
|
||||
// const login = getLogin(parseToken(req));
|
||||
if (!req.query?.login) {
|
||||
throw Error("Nebyl předán login");
|
||||
}
|
||||
const img = getQr(req.query.login as string);
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': img.length
|
||||
});
|
||||
res.end(img);
|
||||
});
|
||||
|
||||
// ----------------------------------------------------
|
||||
@ -181,16 +196,6 @@ app.post("/api/updateChoice", (req, res) => {
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
app.get("/api/qr", (req, res) => {
|
||||
const login = getLogin(parseToken(req));
|
||||
const img = getQr(login);
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': img.length
|
||||
});
|
||||
res.end(img);
|
||||
});
|
||||
|
||||
app.post("/api/updateNote", (req, res) => {
|
||||
const login = getLogin(parseToken(req));
|
||||
if (req.body.note && req.body.note.length > 100) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user