diff --git a/cloudflare/src/tag_manifest/handler.ts b/cloudflare/src/tag_manifest/handler.ts index e0b3336..9d60b02 100644 --- a/cloudflare/src/tag_manifest/handler.ts +++ b/cloudflare/src/tag_manifest/handler.ts @@ -2,6 +2,8 @@ import { TagManifestParams } from "./"; import * as parseDuration from "parse-duration"; import * as moment from "moment"; +const durationRegex = /^(?=\d+[ywdhms])(( ?\d+y)?(?!\d))?(( ?\d+w)?(?!\d))?(( ?\d+d)?(?!\d))?(( ?\d+h)?(?!\d))?(( ?\d+m)?(?!\d))?(( ?\d+s)?(?!\d))?( ?\d+ms)?$/; + export function tryParsePutTagRequest(method: string, url: URL): TagManifestParams | void { const split = url.pathname.split("/"); @@ -66,7 +68,11 @@ export async function handleTagManifestRequest(r: Request, params: TagManifestPa } function expirationFromTag(tag: string): string { - const parsed = parseDuration(tag); + let parsed = parseDuration(tag); + if (!durationRegex.test(tag)) { + // invalid duration, default to 24h + parsed = 24 * 60 * 60 * 1000; + } const now = new Date(); const then = moment(now.getTime() + parsed); return then.fromNow(); diff --git a/hooks/src/controllers/HookAPI.ts b/hooks/src/controllers/HookAPI.ts index 0124323..d9a0847 100644 --- a/hooks/src/controllers/HookAPI.ts +++ b/hooks/src/controllers/HookAPI.ts @@ -18,6 +18,10 @@ const client = redis.createClient({url: process.env["REDISCLOUD_URL"]}); const saddAsync = promisify(client.sadd).bind(client); const hsetAsync = promisify(client.hset).bind(client); +const durationRegex = /^(?=\d+[ywdhms])(( ?\d+y)?(?!\d))?(( ?\d+w)?(?!\d))?(( ?\d+d)?(?!\d))?(( ?\d+h)?(?!\d))?(( ?\d+m)?(?!\d))?(( ?\d+s)?(?!\d))?( ?\d+ms)?$/; +const defaultDuration = 24 * 60 * 60 * 1000; // 24h +const maxDuration = 24 * 60 * 60 * 1000; // 24h + @Controller("/v1/hook") export class HookAPI { /** @@ -50,24 +54,19 @@ export class HookAPI { const imageWithTag = `${image}:${tag}`; - // default to 1h - let expireInSeconds = 60 * 60 * 1000; - console.log(`parsing tag ${tag}`); - const parsed = parseDuration(tag); - if (parsed > 0) { - expireInSeconds = parsed; - - // enforce a max of 24 hours - if (expireInSeconds > 24 * 60 * 60 * 1000) { - expireInSeconds = 24 * 60 * 60 * 1000; - } + let expiresIn = durationfromTag(tag); + if (expiresIn <= 0) { + expiresIn = defaultDuration + } + if (expiresIn > maxDuration) { + expiresIn = maxDuration } await saddAsync("current.images", imageWithTag); const now = new Date().getTime(); - const then = now + expireInSeconds; + const then = now + expiresIn; await hsetAsync(imageWithTag, "created", now, "expires", then); } @@ -76,3 +75,10 @@ export class HookAPI { return {}; } } + +function durationfromTag(tag: string): number { + if (!durationRegex.test(tag)) { + return -1; + } + return parseDuration(tag); +}