feat: proklik na stránky podniku ze stránky objednávek
CI / Generate TypeScript types (push) Successful in 9s
CI / Server unit tests (push) Successful in 21s
CI / Build server (push) Successful in 25s
CI / Build client (push) Successful in 37s
CI / Playwright E2E tests (push) Successful in 1m18s
CI / Build and push Docker image (push) Successful in 39s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 9s
CI / Server unit tests (push) Successful in 21s
CI / Build server (push) Successful in 25s
CI / Build client (push) Successful in 37s
CI / Playwright E2E tests (push) Successful in 1m18s
CI / Build and push Docker image (push) Successful in 39s
CI / Notify (push) Successful in 2s
This commit is contained in:
+43
-7
@@ -1,13 +1,29 @@
|
||||
import { Store } from "../../types/gen/types.gen";
|
||||
import getStorage from "./storage";
|
||||
|
||||
const storage = getStorage();
|
||||
const STORES_KEY = 'stores';
|
||||
|
||||
export async function getStores(): Promise<string[]> {
|
||||
return (await storage.getData<string[]>(STORES_KEY)) ?? [];
|
||||
/**
|
||||
* Vrátí seznam povolených obchodů. Zachovává zpětnou kompatibilitu se starším
|
||||
* formátem, kdy byly obchody uloženy jako pole řetězců (převede je na objekty).
|
||||
*/
|
||||
export async function getStores(): Promise<Store[]> {
|
||||
const raw = await storage.getData<(string | Store)[]>(STORES_KEY);
|
||||
if (!raw) {
|
||||
return [];
|
||||
}
|
||||
return raw.map(s => (typeof s === 'string' ? { name: s } : s));
|
||||
}
|
||||
|
||||
export async function addStore(name: string, heslo: string): Promise<string[]> {
|
||||
/**
|
||||
* Přidá nový obchod do seznamu povolených.
|
||||
*
|
||||
* @param name název obchodu
|
||||
* @param heslo admin heslo
|
||||
* @param url volitelná URL na nabídku podniku
|
||||
*/
|
||||
export async function addStore(name: string, heslo: string, url?: string): Promise<Store[]> {
|
||||
const adminPassword = process.env.ADMIN_PASSWORD;
|
||||
if (!adminPassword || heslo !== adminPassword) {
|
||||
throw new Error('UNAUTHORIZED');
|
||||
@@ -17,21 +33,41 @@ export async function addStore(name: string, heslo: string): Promise<string[]> {
|
||||
throw new Error('Název obchodu nesmí být prázdný');
|
||||
}
|
||||
const stores = await getStores();
|
||||
if (stores.some(s => s.toLowerCase() === trimmed.toLowerCase())) {
|
||||
if (stores.some(s => s.name.toLowerCase() === trimmed.toLowerCase())) {
|
||||
throw new Error('Obchod s tímto názvem již existuje');
|
||||
}
|
||||
const updated = [...stores, trimmed];
|
||||
const trimmedUrl = url?.trim();
|
||||
if (trimmedUrl) {
|
||||
// Povolíme pouze http(s), aby URL nemohla být zneužita (např. javascript: → XSS)
|
||||
let parsed: URL;
|
||||
try {
|
||||
parsed = new URL(trimmedUrl);
|
||||
} catch {
|
||||
throw new Error('Neplatná URL obchodu');
|
||||
}
|
||||
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
||||
throw new Error('URL musí začínat http:// nebo https://');
|
||||
}
|
||||
}
|
||||
const store: Store = trimmedUrl ? { name: trimmed, url: trimmedUrl } : { name: trimmed };
|
||||
const updated = [...stores, store];
|
||||
await storage.setData(STORES_KEY, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
export async function removeStore(name: string, heslo: string): Promise<string[]> {
|
||||
/**
|
||||
* Odebere obchod ze seznamu povolených (dle názvu).
|
||||
*
|
||||
* @param name název obchodu
|
||||
* @param heslo admin heslo
|
||||
*/
|
||||
export async function removeStore(name: string, heslo: string): Promise<Store[]> {
|
||||
const adminPassword = process.env.ADMIN_PASSWORD;
|
||||
if (!adminPassword || heslo !== adminPassword) {
|
||||
throw new Error('UNAUTHORIZED');
|
||||
}
|
||||
const stores = await getStores();
|
||||
const updated = stores.filter(s => s.toLowerCase() !== name.trim().toLowerCase());
|
||||
const updated = stores.filter(s => s.name.toLowerCase() !== name.trim().toLowerCase());
|
||||
await storage.setData(STORES_KEY, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user