Compare commits

..

1 Commits

Author SHA1 Message Date
inecs f35144ed28 Исправлен VERSION до 0.1.3; убран авто-bump из make push.
devops-tools/wrapped/wrapped-deploy/pipeline/head This commit looks good
Упрощён экран «Токен выдан»: чеклист/trust убраны, Share и Download QR — иконки под QR.
2026-07-29 14:15:07 +03:00
10 changed files with 82 additions and 71 deletions
Vendored
+1 -1
View File
@@ -5,7 +5,7 @@
// 2) при успехе — trigger Deploy с wait:false и agent none → Builder-под умирает // 2) при успехе — trigger Deploy с wait:false и agent none → Builder-под умирает
// 3) Deploy стартует отдельно уже без Builder // 3) Deploy стартует отдельно уже без Builder
// //
// Версия образа = VERSION из коммита. Bump: make bump-patch / make push. // Версия образа = VERSION из коммита (без auto-bump). Ручной bump: make bump-patch.
// //
// Credentials (Global): // Credentials (Global):
// harbor-devops-tools-push-pull-access — Harbor devops-tools (robot) // harbor-devops-tools-push-pull-access — Harbor devops-tools (robot)
+3 -3
View File
@@ -32,7 +32,7 @@ help:
@echo " make bump-minor VERSION +0.1.0" @echo " make bump-minor VERSION +0.1.0"
@echo " make release Multi-arch build & push $(FULL_IMAGE)" @echo " make release Multi-arch build & push $(FULL_IMAGE)"
@echo " platforms: $(RELEASE_PLATFORMS)" @echo " platforms: $(RELEASE_PLATFORMS)"
@echo " make push bump-patch + git add/commit (prompt) + push" @echo " make push git add/commit (prompt) + push (без auto-bump)"
@echo " make helm-lint Lint Helm chart" @echo " make helm-lint Lint Helm chart"
@echo " make helm-package Package Helm chart" @echo " make helm-package Package Helm chart"
@echo " make clean Remove containers, volumes, local image" @echo " make clean Remove containers, volumes, local image"
@@ -136,7 +136,7 @@ clean:
-docker buildx rm $(BUILDX_BUILDER) 2>/dev/null || true -docker buildx rm $(BUILDX_BUILDER) 2>/dev/null || true
rm -rf dist rm -rf dist
# Same flow as proxmox_api_simulator / infra: bump SemVer, stage, multiline commit, push. # Ручной SemVer (не вызывается из make push).
bump-patch: bump-patch:
@PYTHONPATH=. python3 scripts/bump_version.py patch @PYTHONPATH=. python3 scripts/bump_version.py patch
@echo "VERSION → $$(cat VERSION)" @echo "VERSION → $$(cat VERSION)"
@@ -153,7 +153,7 @@ version-commit:
git commit -m "Bump version to $$(cat VERSION)."; \ git commit -m "Bump version to $$(cat VERSION)."; \
fi fi
push: bump-patch push:
@set -e; \ @set -e; \
git add .; \ git add .; \
echo "=== staged ==="; \ echo "=== staged ==="; \
+3 -3
View File
@@ -340,7 +340,7 @@ services:
### UX (v0.1.3+) ### UX (v0.1.3+)
- После создания: **QR** на share-link, **скачать QR (PNG)**, **Web Share** (если есть `navigator.share`), чеклист и trust-строка про `#key`; отдельные кнопки Copy для ссылки / токена / пароля; пароль не советуется слать в той же переписке. - После создания: **QR** на share-link, иконки **скачать QR (PNG)** и **Web Share** (если есть `navigator.share`) под QR; отдельные кнопки Copy для ссылки / токена / пароля; пароль не советуется слать в той же переписке.
- Create: счётчик размера `≈ used / max` и предупреждение near-limit (сверх лимита — `create.tooLarge`). - Create: счётчик размера `≈ used / max` и предупреждение near-limit (сверх лимита — `create.tooLarge`).
- Unwrap: Enter в поле пароля отправляет форму; после `password_required` / `bad_password` — focus+select; при ≥2 элементах — **скачать всё** (zip через JSZip); trust-строка на результате; спокойный экран «ссылка недоступна» для already used / expired (anti-enumeration); отдельные состояния для `password_locked`, rate limit, CAPTCHA, ошибки расшифровки. - Unwrap: Enter в поле пароля отправляет форму; после `password_required` / `bad_password` — focus+select; при ≥2 элементах — **скачать всё** (zip через JSZip); trust-строка на результате; спокойный экран «ссылка недоступна» для already used / expired (anti-enumeration); отдельные состояния для `password_locked`, rate limit, CAPTCHA, ошибки расшифровки.
- Картинки после unwrap: inline-превью и **lightbox** (тап/клик). - Картинки после unwrap: inline-превью и **lightbox** (тап/клик).
@@ -452,8 +452,8 @@ docker buildx build \
| Где | Поведение | | Где | Поведение |
|-----|-----------| |-----|-----------|
| UI (модалка «?») | бейдж `vX.Y.Z` | | UI (модалка «?») | бейдж `vX.Y.Z` |
| `make bump-patch` / `bump-minor` | ручной bump | | `make bump-patch` / `bump-minor` | ручной bump (по желанию) |
| `make push` | автоматически `bump-patch`, затем commit/push | | `make push` | commit/push **без** auto-bump |
| Jenkins (`Jenkinsfile`) | читает `VERSION` из коммита **без** доп. bump → те же теги в образе и на кластере | | Jenkins (`Jenkinsfile`) | читает `VERSION` из коммита **без** доп. bump → те же теги в образе и на кластере |
Что в `VERSION` запушили — то и уйдёт в Harbor/Hub/деплой (и в футер модалки внутри образа). Что в `VERSION` запушили — то и уйдёт в Harbor/Hub/деплой (и в футер модалки внутри образа).
+1 -1
View File
@@ -1 +1 @@
0.1.4 0.1.3
+56 -40
View File
@@ -322,46 +322,6 @@ html[data-theme="dark"] .icon-btn:hover {
font-size: 0.84rem; font-size: 0.84rem;
line-height: 1.4; line-height: 1.4;
} }
.success-checklist {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 0.35rem;
}
.success-checklist li {
position: relative;
padding-left: 1.35rem;
color: var(--muted);
font-size: 0.88rem;
line-height: 1.4;
}
.success-checklist li::before {
content: "";
position: absolute;
left: 0;
top: 0.35rem;
width: 0.55rem;
height: 0.55rem;
border-radius: 2px;
border: 1.5px solid var(--accent-2);
opacity: 0.85;
}
.success-trust {
margin: 0;
font-size: 0.84rem;
line-height: 1.45;
}
.success-actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.35rem;
}
.success-actions .btn {
flex: 1 1 auto;
min-width: 8rem;
}
.size-meter { .size-meter {
margin: 0; margin: 0;
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
@@ -381,6 +341,7 @@ html[data-theme="dark"] .icon-btn:hover {
border-radius: 16px; border-radius: 16px;
background: var(--panel); background: var(--panel);
min-width: 0; min-width: 0;
overflow: visible;
} }
.share-qr { .share-qr {
width: 180px; width: 180px;
@@ -405,6 +366,61 @@ html[data-theme="dark"] .icon-btn:hover {
max-width: 11rem; max-width: 11rem;
line-height: 1.35; line-height: 1.35;
} }
.success-qr-actions {
display: flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
margin-top: 0.15rem;
}
.qr-action-btn {
position: relative;
width: 2.35rem;
height: 2.35rem;
border: 1px solid var(--line);
border-radius: 10px;
background: transparent;
color: var(--muted);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.qr-action-btn:hover,
.qr-action-btn:focus-visible {
color: var(--accent-2);
background: rgba(75, 134, 240, 0.1);
border-color: rgba(75, 134, 240, 0.35);
outline: none;
}
.qr-action-btn:active {
transform: scale(0.96);
}
.qr-action-btn .ui-tooltip {
left: 50%;
right: auto;
bottom: calc(100% + 0.5rem);
transform: translateX(-50%) translateY(4px);
white-space: nowrap;
}
.qr-action-btn .ui-tooltip::after {
left: 50%;
right: auto;
transform: translateX(-50%);
}
.qr-action-btn:hover .ui-tooltip,
.qr-action-btn:focus-visible .ui-tooltip {
opacity: 1;
visibility: visible;
transform: translateX(-50%);
}
.success-panel > .expires-meta {
width: 100%;
justify-self: stretch;
margin-top: 0.15rem;
}
@media (max-width: 860px) { @media (max-width: 860px) {
.success-layout { .success-layout {
grid-template-columns: 1fr; grid-template-columns: 1fr;
-3
View File
@@ -31,7 +31,6 @@
expiresMeta: document.getElementById("expires-meta"), expiresMeta: document.getElementById("expires-meta"),
captchaSlot: document.getElementById("captcha-slot"), captchaSlot: document.getElementById("captcha-slot"),
sizeMeter: document.getElementById("size-meter"), sizeMeter: document.getElementById("size-meter"),
checkPasswordItem: document.getElementById("check-password-item"),
shareNative: document.getElementById("share-native"), shareNative: document.getElementById("share-native"),
downloadQr: document.getElementById("download-qr"), downloadQr: document.getElementById("download-qr"),
}; };
@@ -334,11 +333,9 @@
if (password) { if (password) {
els.sharePassword.value = password; els.sharePassword.value = password;
els.passwordBlock.classList.remove("hidden"); els.passwordBlock.classList.remove("hidden");
els.checkPasswordItem?.classList.remove("hidden");
} else { } else {
els.sharePassword.value = ""; els.sharePassword.value = "";
els.passwordBlock.classList.add("hidden"); els.passwordBlock.classList.add("hidden");
els.checkPasswordItem?.classList.add("hidden");
} }
renderShareQr(link); renderShareQr(link);
syncShareControls(); syncShareControls();
+14 -16
View File
@@ -66,15 +66,6 @@
</span> </span>
</div> </div>
<ul class="success-checklist" id="success-checklist">
<li data-i18n="create.checkLink">Copy the share link</li>
<li id="check-password-item" class="hidden" data-i18n="create.checkPassword">Send the password in a separate message</li>
<li data-i18n="create.checkExpires">Note the expiry time</li>
</ul>
<p class="hint success-trust" data-i18n="create.trustKey">
The encryption key lives only in the link #fragment — the server never sees it.
</p>
<div class="success-layout"> <div class="success-layout">
<div class="success-main"> <div class="success-main">
<div id="success-password-block" class="success-password-block hidden"> <div id="success-password-block" class="success-password-block hidden">
@@ -103,21 +94,28 @@
<input id="share-token" class="mono" readonly /> <input id="share-token" class="mono" readonly />
<button type="button" class="btn" id="copy-token" data-i18n="common.copy">Copy</button> <button type="button" class="btn" id="copy-token" data-i18n="common.copy">Copy</button>
</div> </div>
<div class="success-actions">
<button type="button" class="btn hidden" id="share-native" data-i18n="create.share">Share</button>
<button type="button" class="btn" id="download-qr" data-i18n="create.downloadQr">Download QR</button>
</div>
<p class="expires-meta" id="expires-meta"></p>
</div> </div>
<div class="success-qr" aria-label="QR code"> <div class="success-qr" aria-label="QR code">
<div id="share-qr" class="share-qr"></div> <div id="share-qr" class="share-qr"></div>
<p class="hint success-qr-hint" data-i18n="create.qrHint">Scan to open the share link</p> <p class="hint success-qr-hint" data-i18n="create.qrHint">Scan to open the share link</p>
<div class="success-qr-actions">
<button type="button" class="qr-action-btn hidden" id="share-native" aria-describedby="share-native-tip">
<i class="fa-solid fa-share-nodes" aria-hidden="true"></i>
<span class="sr-only" data-i18n="create.share">Share</span>
<span class="ui-tooltip" id="share-native-tip" role="tooltip" data-i18n="create.share">Share</span>
</button>
<button type="button" class="qr-action-btn" id="download-qr" aria-describedby="download-qr-tip">
<i class="fa-solid fa-download" aria-hidden="true"></i>
<span class="sr-only" data-i18n="create.downloadQr">Download QR</span>
<span class="ui-tooltip" id="download-qr-tip" role="tooltip" data-i18n="create.downloadQr">Download QR</span>
</button>
</div>
</div> </div>
</div> </div>
<p class="expires-meta" id="expires-meta"></p>
<button type="button" class="btn ghost" id="create-another" data-i18n="create.another">Create another</button> <button type="button" class="btn ghost" id="create-another" data-i18n="create.another">Create another</button>
</div> </div>
</section> </section>
+2 -2
View File
@@ -2,5 +2,5 @@ apiVersion: v2
name: wrapped name: wrapped
description: Zero-knowledge one-time encrypted drop (Wrapped) description: Zero-knowledge one-time encrypted drop (Wrapped)
type: application type: application
version: 0.1.4 version: 0.1.3
appVersion: "0.1.4" appVersion: "0.1.3"
+1 -1
View File
@@ -2,7 +2,7 @@ replicaCount: 1
image: image:
repository: inecs/wrapped repository: inecs/wrapped
tag: "0.1.4" tag: "0.1.3"
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
service: service:
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "wrapped" name = "wrapped"
version = "0.1.4" version = "0.1.3"
description = "Zero-knowledge one-time encrypted drop service" description = "Zero-knowledge one-time encrypted drop service"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"