diff --git a/lambda/admin_portal/static/links.html b/lambda/admin_portal/static/links.html
index 23af538..f953bfa 100644
--- a/lambda/admin_portal/static/links.html
+++ b/lambda/admin_portal/static/links.html
@@ -241,8 +241,8 @@
-
英数字、ハイフン、アンダースコアのみ使用可能
+ pattern="[a-zA-Z0-9_\-/]+" title="英数字、ハイフン、アンダースコア、スラッシュのみ使用可能">
+
英数字、ハイフン、アンダースコア、スラッシュのみ使用可能
@@ -522,7 +522,7 @@
e.stopPropagation();
const slugInput = document.getElementById('linkSlug');
- const slugPattern = /^[a-zA-Z0-9_-]+$/;
+ const slugPattern = /^[a-zA-Z0-9_\-/]+$/;
if (!slugInput.value) {
alert('Slugを入力してください。');
@@ -530,7 +530,7 @@
}
if (!slugPattern.test(slugInput.value)) {
- alert('Slugは英数字、ハイフン、アンダースコアのみ使用可能です。');
+ alert('Slugは英数字、ハイフン、アンダースコア、スラッシュのみ使用可能です。');
return;
}
diff --git a/lambda/layers/common/python/ddb/models/delibird_link.py b/lambda/layers/common/python/ddb/models/delibird_link.py
index 0c2cc41..80dae1a 100644
--- a/lambda/layers/common/python/ddb/models/delibird_link.py
+++ b/lambda/layers/common/python/ddb/models/delibird_link.py
@@ -1,6 +1,7 @@
import json
import logging
import os
+import re
from dataclasses import dataclass
from datetime import datetime
from enum import Enum, auto
@@ -18,6 +19,8 @@
from util.logger_util import setup_logger
_REGION = os.environ["AWS_REGION"]
+_MAX_SLUG_LENGTH = 255
+_SLUG_PATTERN = re.compile(r'^[a-zA-Z0-9\-_]+(?:/[a-zA-Z0-9\-_]+)*$', re.ASCII)
logger = setup_logger("delibird.link_table", logging.INFO)
@@ -55,11 +58,27 @@ class DelibirdLink:
max_uses: Optional[int] = None
+ @staticmethod
+ def _validation(link: "DelibirdLink") -> None:
+ # domain
+ if not link.domain:
+ raise ValueError("Domain is required.")
+ # slug
+ if (not (slug := link.link_slug)) or (len(slug) > _MAX_SLUG_LENGTH) or (not _SLUG_PATTERN.fullmatch(slug)):
+ raise ValueError(f"Invalid slug: {slug}")
+ # origin
+ if not link.link_origin:
+ raise ValueError("Origin is required.")
+ # status
+ if not link.status.is_redirection:
+ raise ValueError(f"Status code {link.status} is not a redirection status.")
+
def __post_init__(self):
if self.query_whitelist is None:
self.query_whitelist = set()
if self.tag is None:
self.tag = set()
+ DelibirdLink._validation(self)
def check_active(self) -> tuple[bool, Optional[DelibirdLinkInactiveReason]]:
if self.disabled:
diff --git a/s3/css/admin-portal.css b/s3/css/admin-portal.css
index 674ca4f..7d26cb9 100644
--- a/s3/css/admin-portal.css
+++ b/s3/css/admin-portal.css
@@ -64,6 +64,10 @@
max-width: 50px;
}
+.tooltip-inner {
+ max-width: 400px;
+}
+
.table-responsive {
font-size: 0.9rem;
}