From 549a58dc5d4e8f57c3e123b265895e2a37a3d7e9 Mon Sep 17 00:00:00 2001 From: magdev Date: Mon, 26 Jan 2026 15:29:57 +0100 Subject: [PATCH] Add per-license customer secrets for API response verification - Add static methods to ResponseSigner for deriving customer-specific secrets - Display "API Verification Secret" in customer account licenses page - Add collapsible secret section with copy button - Update server-implementation.md with per-license secret documentation - Update translations with new strings Each customer now gets a unique verification secret derived from their license key, eliminating the need to share the master server secret. Co-Authored-By: Claude Opus 4.5 --- assets/css/frontend.css | 115 +++ assets/js/frontend.js | 45 + composer.lock | 12 +- docs/server-implementation.md | 46 +- languages/wc-licensed-product-de_CH.mo | Bin 34134 -> 34090 bytes languages/wc-licensed-product-de_CH.po | 1050 ++++++++++++------------ languages/wc-licensed-product.pot | 996 +++++++++++----------- src/Api/ResponseSigner.php | 49 +- src/Frontend/AccountController.php | 3 + templates/frontend/licenses.html.twig | 20 + 10 files changed, 1306 insertions(+), 1030 deletions(-) diff --git a/assets/css/frontend.css b/assets/css/frontend.css index d7eeb07..4ec55ac 100644 --- a/assets/css/frontend.css +++ b/assets/css/frontend.css @@ -863,3 +863,118 @@ color: #2271b1; font-weight: 500; } + +/* Customer Secret Section */ +.license-row-secret { + margin-top: 0.75em; + padding-top: 0.75em; + border-top: 1px dashed #e5e5e5; +} + +.secret-toggle { + display: inline-flex; + align-items: center; + gap: 0.35em; + padding: 0.4em 0.75em; + background: transparent; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 0.85em; + color: #666; + cursor: pointer; + transition: all 0.2s ease; +} + +.secret-toggle:hover { + background: #f5f5f5; + border-color: #ccc; + color: #333; +} + +.secret-toggle .dashicons { + font-size: 14px; + width: 14px; + height: 14px; +} + +.secret-toggle .toggle-arrow { + transition: transform 0.2s ease; +} + +.secret-toggle[aria-expanded="true"] .toggle-arrow { + transform: rotate(180deg); +} + +.secret-content { + margin-top: 0.75em; + padding: 1em; + background: #f8f9fa; + border-radius: 4px; + border: 1px solid #e5e5e5; +} + +.secret-description { + margin: 0 0 0.75em 0; + font-size: 0.85em; + color: #666; +} + +.secret-value-wrapper { + display: flex; + align-items: center; + gap: 0.5em; +} + +.secret-value { + font-family: 'SF Mono', Monaco, Consolas, monospace; + font-size: 0.75em; + background: #fff; + padding: 0.5em 0.75em; + border: 1px solid #ddd; + border-radius: 4px; + word-break: break-all; + flex: 1; + min-width: 0; + overflow-x: auto; +} + +.copy-secret-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + padding: 0; + background: #f0f0f0; + border: 1px solid #ddd; + border-radius: 4px; + cursor: pointer; + transition: all 0.2s ease; + flex-shrink: 0; +} + +.copy-secret-btn:hover { + background: #e5e5e5; + border-color: #ccc; +} + +.copy-secret-btn .dashicons { + font-size: 18px; + width: 18px; + height: 18px; +} + +@media screen and (max-width: 768px) { + .secret-value-wrapper { + flex-direction: column; + align-items: stretch; + } + + .secret-value { + font-size: 0.7em; + } + + .copy-secret-btn { + align-self: flex-start; + } +} diff --git a/assets/js/frontend.js b/assets/js/frontend.js index 8fce961..4d0f3bf 100644 --- a/assets/js/frontend.js +++ b/assets/js/frontend.js @@ -19,6 +19,7 @@ bindEvents: function() { $(document).on('click', '.copy-license-btn', this.copyLicenseKey); + $(document).on('click', '.copy-secret-btn', this.copySecret); // Transfer modal events $(document).on('click', '.wclp-transfer-btn', this.openTransferModal.bind(this)); @@ -28,6 +29,9 @@ // Older versions toggle $(document).on('click', '.older-versions-toggle', this.toggleOlderVersions); + // Secret toggle + $(document).on('click', '.secret-toggle', this.toggleSecret); + // Close modal on escape key $(document).on('keyup', function(e) { if (e.key === 'Escape') { @@ -50,6 +54,47 @@ $list.slideToggle(200); }, + /** + * Toggle secret visibility + */ + toggleSecret: function(e) { + e.preventDefault(); + + var $btn = $(this); + var $content = $btn.siblings('.secret-content'); + var isExpanded = $btn.attr('aria-expanded') === 'true'; + + $btn.attr('aria-expanded', !isExpanded); + $content.slideToggle(200); + }, + + /** + * Copy secret to clipboard + */ + copySecret: function(e) { + e.preventDefault(); + + var $btn = $(this); + var secret = $btn.data('secret'); + + if (!secret) { + return; + } + + // Use modern clipboard API if available + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(secret) + .then(function() { + WCLicensedProductFrontend.showCopyFeedback($btn, true); + }) + .catch(function() { + WCLicensedProductFrontend.fallbackCopy(secret, $btn); + }); + } else { + WCLicensedProductFrontend.fallbackCopy(secret, $btn); + } + }, + /** * Copy license key to clipboard */ diff --git a/composer.lock b/composer.lock index dde8214..f5c4e11 100644 --- a/composer.lock +++ b/composer.lock @@ -380,16 +380,16 @@ }, { "name": "symfony/http-client", - "version": "v7.4.3", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616" + "reference": "d63c23357d74715a589454c141c843f0172bec6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/d01dfac1e0dc99f18da48b18101c23ce57929616", - "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d63c23357d74715a589454c141c843f0172bec6c", + "reference": "d63c23357d74715a589454c141c843f0172bec6c", "shasum": "" }, "require": { @@ -457,7 +457,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.4.3" + "source": "https://github.com/symfony/http-client/tree/v7.4.4" }, "funding": [ { @@ -477,7 +477,7 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:50:43+00:00" + "time": "2026-01-23T16:34:22+00:00" }, { "name": "symfony/http-client-contracts", diff --git a/docs/server-implementation.md b/docs/server-implementation.md index f7fde97..71add02 100644 --- a/docs/server-implementation.md +++ b/docs/server-implementation.md @@ -8,14 +8,16 @@ The security model works as follows: 1. Server generates a unique signature for each response using HMAC-SHA256 2. Signature includes a timestamp to prevent replay attacks -3. Client verifies the signature using a shared secret -4. Invalid signatures cause the client to reject the response +3. Each license key has a unique derived secret (not the master secret) +4. Client verifies the signature using their per-license secret +5. Invalid signatures cause the client to reject the response This prevents attackers from: - Faking valid license responses - Replaying old responses - Tampering with response data +- Using one customer's secret to verify another customer's responses ## Requirements @@ -323,13 +325,49 @@ Adjust if needed: $signature = new ResponseSignature($key, timestampTolerance: 600); // 10 minutes ``` +### Per-License Secrets + +Each customer receives a unique secret derived from their license key. This means: + +- Customers only know their own secret, not the master server secret +- If one customer's secret is leaked, other customers are not affected +- The server uses HKDF-like derivation to create unique secrets + +#### How Customers Get Their Secret + +Customers can find their per-license verification secret in their account: + +1. Log in to the store +2. Go to My Account > Licenses +3. Click "API Verification Secret" under any license +4. Copy the 64-character hex string + +This secret is automatically derived from the customer's license key and the server's master secret. + +#### Using the Customer Secret + +```php +use Magdev\WcLicensedProductClient\SecureLicenseClient; +use Symfony\Component\HttpClient\HttpClient; + +// Customer uses their per-license secret (from account page) +$client = new SecureLicenseClient( + httpClient: HttpClient::create(), + baseUrl: 'https://shop.example.com', + serverSecret: 'customer-secret-from-account-page', // 64 hex chars +); + +$info = $client->validate('XXXX-XXXX-XXXX-XXXX', 'example.com'); +``` + ### Secret Key Rotation To rotate the server secret: 1. Deploy new secret to server -2. Update client configurations -3. Old signatures become invalid immediately +2. All per-license secrets change automatically (they're derived) +3. Customers must copy their new secret from their account page +4. Old signatures become invalid immediately For zero-downtime rotation, implement versioned secrets: diff --git a/languages/wc-licensed-product-de_CH.mo b/languages/wc-licensed-product-de_CH.mo index eff35d715dd50ce07a1fdc683059f4b9c93c3404..d0f5597c46e3be27d66222060c6b8c47fb156d6a 100644 GIT binary patch delta 6501 zcmXxo33!cH9>?)>BSJ!AjVt>_B8nuI*l7|J5lU=LERBdO(vqZEQM|Nhd8$LNWvHsQ zqfHgn2Gw@z(R7=dc3P(O)O6FD8Hz4r8Ld8;?=R<_dC2FS^S z;G3>LbTN*}p~1^rv#;Q+y%Gv4wp!w4tFM3-LW%g~?rQX7-{oa1iz0F=Q_0r2G6jMo_Rn&2a-Ol(1A)cF$y&EyC&d2<4T@mEyDH&GvivcQVKiyE*q#$zU` z;{wdYQcS^@F&n?eo|xRjem@0!Q!hYbb<9Qzn!xL*)Sko`{3kX;eXU5FBOe$aw!kr{ z=TmSX&cx=p88zXZ*a`Py82-&|Kka%BBN*RYYb+2o)7Avqp(c=oQJCdA1C^m_R0ejq z?QbASGM^!T%q@Nl$DXM+urk#9kD?EsciTU}D8@HuC}@ptpw_rgnw`KP97cUA>NEsU z6WouQ*f9*pf1q~rc?`v$a3cPSxtQIHlYvj-Y&?g`$e7;bzZHea6to0Is1zGr#BsQw0GOB|U_{*}U98rot3 zs)Gu*{xE9uZE@X?IQ8Yq4r3t{$ve@ITUnm zD^VB92JC=`P#=DT8t7Z(PBJ%9OVx!9nLgf&k#G2NYw6+L%o-bk=PGe zC6j}i$O=^C8?mj<|8@$TJhKmV!F+}KAb6-T0S%pgJYp5kV<@!4+Gd_Nh zZF4VblWxIrxEqzR%c$>eU~8TK1kQwJ)(f@fS*RIKK}9ml^?tW~F)AYup_XW^Ti=En zU>7QoI#hq3Vl19TW!Plc@6*uny+2D}e7u_c&*kD`uK z9crLMs3km!?ePcKTc~l`W!m==GRc2O8ivxKj;Ep`_oE^yMMY49F}M~L`EDGIdr<>k zMZMo9%Nm6WtP`sLuBd)8P@8ZP_CY7hY0QRsm4Ii<_o8mvWGuv7%toi4LJftRs5Px3uSxh2s$PdI zn>mb{z<*H@G#z6HXp1`c(dfk_)KU$@ILyZstVJ!sZnymiHfMZuiUJpb`4%<6e^3K! zdWtZ@H34v(_~fBd{{ZSduSPA=c2vZ5s2lGfZo^BMjB7}nGP57m z{}0HuZ!Wv-Jtvd@avF*!^D=&ct+8N=-8|)}4s@@URZ)fE9n(2!QV8K-KuNRll&>mOgD%_5HFkzaVz;V>>{yXZNUqo%f5b~-C zj=)wp4wbo?n2vL>0JmaGyp9PNoM!_}bSUWD4o5}i$4Fd>{C+T7QET}*YM?A`sSq5C zy7_WZ=f4zvxE{5K_G3>xjG1^AHNnK`HdE=SfSnN()IlC<^VFg;vK!mr0aU6R-1bwL zNc}tPh9NU-X3~&-X-4B<+=4Ul1S%7$RMc+~a@Uzs%+UF-r_hy#E2tSo&$4TphWcO> zDrLFYA0I%ibscJLU&CSeHtPM`sOMq#+KVg-6?q0KkO|lpiyG?=x1al99d_WsPSg!} z$n{Iq1U&`zxOGEiDi77Z1_$9j)WvfS**@lu*)~HC>is%Q!&BIpxkBD?Xh@?l3iDBG zw+myi4mm02UDUbt&an{;!C2}OP@8H2>Y`bU+SSW(Ha><&GXN<;Bdh3LVsQM_>nirxr?+#RoUv;0qhf4h!xe1M#Si2f9u}Emajx#|=0cFJb~_l-T|X zP#LMhzW4|#@HZU_>hL*v^MGC>Zb7>d83CUgVGV0f7wU>Yit zg&2V~sLi$-eYg$B;v1;V+O*sT=)-pGKhuN4KptdZZ(M|ma1Ux%U&1>u`2qX?UURV< z^$n=+UdMF2j9l*~xq|GVgW>pB)ZRFa%2;}(?QbZyVtg}?LTju+FFt~b=xM!xb?);c zZv8`4Moy#NKZ{}byK6|5y(!yZ8`{U9_Rw@3fQwP5>lJj=(Gdz-f(FzYeu=tR&beMi zec-9KYuVg24!hFc2Q}e*)IBl>l_3XpI_gmO$GfONzrh~(b2a(bz%e!U;z&oOY%D5O zd2ah`OrlRQJKApv(V!_X#X8v zfP-jw5%t1ZR3?5wt>G;U1CF+8zr(tItjziFoG58E>Y2U(j_yMZ_FL514F5^G* zqO*&_CJJH8ZHG@|I`vmE63-#mzPX9&Xbu@`JZ7kruSRXY^{9*NkJt$hV?2I=!|*zK zvEK^&d_1ye98*T20}mFVBKiX=;%8AG9K`nc5o!Y8;ZVGWeX!3;J5fIdQGXD%HT+Wm19Jox|ru{X@j`kUUf9#28wyQnhHJ%QZlA)(!9 zZozv~0-K}DJgoywV{$wukQf3j-%&U-H}= zSQgjCGd1u`+=S3s?m&|Qzs2Q5=2P22w+HyEoHg)wb|61KEpiS|22f*aW;kU(f2ReW ziq8n*ze9c#U+S427@y$vtG7ghMH z>X&w&mXtBI((kL9UsCC-Y;5#ZmHBG)?qXkMNpY!vu1{ZA_$$lHN-O=9slFV)zuZ?+ zrPr$~{HgUPMo;tvp3Cl7zdZYLlXeRWi|6`l`lj~EEM8bxvLLmnY+-%*_=YA?^paxd zu%yIaQC(VGnc~i(HuqS{Tprc>OXvETTZ!K{x5Up_?lgP)suwoSh3~5TnodeqX;p0* xl~Ui5YCGE!_3AH8^$qve7S5;C*bjYFmK4qRSNIC6=cU&7cQ$+KJFiR+{vX?yZCL;S delta 6518 zcmb`~d01Cf9>?+fV{t(R6cE{eptu7fxZ;9>3!xeAn3AABkx@Yrx74nbI;A~j{=OUGn#wB{L?oHDbNGAqY&!lum3DI0CkY~CNw>5utyo@aWL*E#3jdzSC{o`daN z6L4ltz`6}?mg6`DDUQ<^mtzxLg^lnL48x7s40m8Fd=Z=DQENSRrv5S3V$-&cy4V6g!dUzgL$Fb*<3wOfRC_9hV=hKv5o$u^s0GxZ zzFUr3$b+bUA4UE+Tlo=;uco@D@CFSnX*h|c_zAAWy!IwC$50VCg?jHCGB@XneIC)l zaYCubp(fB7dtnxi#962b9l!)UifypLrI1A721a9CN3*gl>_a^ti}5~egdbSXqu&1v z)!{9S$M{ZW!hMiG&LDnhBC}8v`~xZydr=W}4^hxeP9uwPzQQ1kWJ9&$7}N);s1;

YSoou~hffag%j9G6A>6}l8| zAx&Te^2hP8vpe~s2Q6G5wnY|i^+M)-rJ3fgD>AR>cyK0Rl zEQ(A&eh_u%UR09q#SwTI6|qo`fWB*u;X400D&PoIB&MKdI2W~&CDvct_Km2BJb}vU z9k%`wYJk6>7IGBT-(`%)pHUHxA85Y63*8_ZCQ#6^n2g%Xnf8TBR7e-tx{DfcHELpy zV-h}vI!;GX1J$Fp@Crs^aIP^HHBJWVy_{U)--g0O8r1PT)XHm7D_MhD!Fr6t9jKKb z#$k92)lv8$^M0DO2WnycQT-1_^>a5W2`jNXZXV=vlqkGSLotSuS+j5^a_KpzaV|E> zGkd-WW2irF-GlssbB<#yUPI+lc)rIK*O zFe);eP|5ThDnk2FIdd2j@f}RTZ&0C+9BLxc1@(Ov>ZZ-ZQk;VY=$@pokU|Xc)Sj-x zRD8nLkD>;C2Q{%zurXdio%ib)jh^9Vi()W=dJjy)F{sej+V&0Dg!*3OB66KqC}@DU zP!l+ZTG=J*4b(Yr&U6Wu-cYSi(531f8r zFHukjL4~Hn*4UH!AkiGPK8JIqTTN6uATeusW;TPBhuVE10!e9&>X%^NL z^*mNGzSEXMm50nkg?7uG=H`0J`Z9K*{S<28o3`GS(N&*_%rr`;kg+JQ*jJr7E z)Hh&Tyo|{hUS#sj=}tj2T8trBi<;TENreh`(O^6Ah7g5Le=9+=<2G%>;sopR&9K#$qZe z33E{sT#jM58Wp+6F&nqwJy?&;F>|81F$bU)SmIL9xm|`@**1*ASCHQqPCaTb!?>L^ z&{AxKD^VBATGaV}7QOg7Du*s&SNs}tF=3LKU{}d&OZ#+H)})E0DZ&YOyb#!pYc-ABx0GRKHtM$M{(ssPq37h4wV0O))bX zi`vr))CVgt3D=^I<@2Z&G@$nS8|;raQ1ACCG0*c+7ugup)+|9S zQPjX6pg#PUHHr!PE+q zv`bJE*o2D6Zp^~NsD)p1DX7EDUzuMvqtHwJKGeY5FcJ4*XME4rbt!b9o`gv_43%8v z=*8clwrIb7eik*6AFW}t&3)pwqwpjT(vZ8tc^gBp;~X>NEbCD0LVGc4i&kM{d>sSv zBsRl$F$mA27Vs%*;2WrwhgX_ zhk5}U?DMO(9#~@{5`lU@0kxtY)?DmKy%1aC{iqz;fW5E|b-KPpSE0R1L0fPWwTDp) z%*B#yO-Fr@gONDcIsw~LpN*QZA9asxK}F~Q>U1=qPR}jWLfb4fxzuSP@z=oPXo$i} zRLEAMLbcwu{|-~B??FxE3=YSS(2MOCnfHfTN1@)EfYDfDU5MJUN3aLJzKHm1kAI?p z+tTU1n6r(WQ7?op;hM#KR0!Wjt?(<1!H|1R&a^|VbUgONYD~lD(2MV*`uiT6WBO8a zHRre#3TW7beeeS6g@k1$5}i?d*c)5n9jGmuV(S%{LVX$L;5LlIzoWMHJB&cja?^hl zuAx2(E6_blVFQKy`^*3zVm9^5s4Yn*Lh7Iw>Ub5Rwq_D4>B=wx=U_6fMMY{C_Qw+# zjUg+{^AuFBG8T?OQNW=l^{Q>fkzR&ze7A_Np&-ral*E;AYIlfR*MZ%fr#s7ok>q z9JMt~R+-R8q9T=O>+Mm;xf?11x!7FUUqHcwzx+pzICt0m6n(+tDe-?2Q{@@&FN)1+ z`Yp}PcyEkomNw^(3f5}HD!Ei-SuIkJpP6itup`T@BJ$ZV(X?9 zTn(%%8+jyf2s0@2Rld5frlP#&zot++d;TvIsPI+S_`C}=hgrSIMsuxt2 fr`Po_I+Rvd=5Dw>r@a3|kN(Wsq`HXO=%D`q_{w#s diff --git a/languages/wc-licensed-product-de_CH.po b/languages/wc-licensed-product-de_CH.po index 1e3fbdb..f2b3300 100644 --- a/languages/wc-licensed-product-de_CH.po +++ b/languages/wc-licensed-product-de_CH.po @@ -4,8 +4,8 @@ msgid "" msgstr "" "Project-Id-Version: WC Licensed Product 0.5.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-25 18:32+0100\n" +"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" +"POT-Creation-Date: 2026-01-26 15:26+0100\n" "PO-Revision-Date: 2026-01-25T18:30:00+00:00\n" "Last-Translator: Marco Graetsch \n" "Language-Team: German (Switzerland) \n" @@ -15,240 +15,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/Admin/VersionAdminController.php:58 -msgid "Product Versions" -msgstr "Produktversionen" - -#: src/Admin/VersionAdminController.php:78 -msgid "Add New Version" -msgstr "Neue Version hinzufügen" - -#: src/Admin/VersionAdminController.php:81 -#: src/Admin/VersionAdminController.php:136 src/Admin/AdminController.php:1609 -msgid "Version" -msgstr "Version" - -#: src/Admin/VersionAdminController.php:84 -msgid "Use semantic versioning (e.g., 1.0.0)" -msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)" - -#: src/Admin/VersionAdminController.php:88 -#: src/Admin/VersionAdminController.php:137 -msgid "Download File" -msgstr "Download-Datei" - -#: src/Admin/VersionAdminController.php:93 -msgid "Select File" -msgstr "Datei auswählen" - -#: src/Admin/VersionAdminController.php:96 -#: src/Admin/VersionAdminController.php:110 -msgid "Remove" -msgstr "Entfernen" - -#: src/Admin/VersionAdminController.php:98 -msgid "" -"Upload or select a file from the media library. Version will be auto-" -"detected from filename (e.g., plugin-v1.2.3.zip)." -msgstr "" -"Laden Sie eine Datei hoch oder wählen Sie eine aus der Mediathek. Die " -"Version wird automatisch aus dem Dateinamen erkannt (z.B. plugin-v1.2.3.zip)." - -#: src/Admin/VersionAdminController.php:102 -msgid "Checksum File" -msgstr "Prüfsummendatei" - -#: src/Admin/VersionAdminController.php:107 -msgid "Select Checksum File" -msgstr "Prüfsummendatei auswählen" - -#: src/Admin/VersionAdminController.php:112 -msgid "" -"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity." -msgstr "" -"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die " -"Dateiintegrität zu überprüfen." - -#: src/Admin/VersionAdminController.php:116 -#: src/Admin/VersionAdminController.php:139 -msgid "Release Notes" -msgstr "Versionshinweise" - -#: src/Admin/VersionAdminController.php:124 -msgid "Add Version" -msgstr "Version hinzufügen" - -#: src/Admin/VersionAdminController.php:132 -msgid "Existing Versions" -msgstr "Vorhandene Versionen" - -#: src/Admin/VersionAdminController.php:138 -msgid "SHA256" -msgstr "SHA256" - -#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 -#: src/Admin/AdminController.php:1446 src/Admin/OrderLicenseController.php:206 -msgid "Status" -msgstr "Status" - -#: src/Admin/VersionAdminController.php:141 -msgid "Released" -msgstr "Veröffentlicht" - -#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 -#: src/Admin/AdminController.php:1449 src/Admin/OrderLicenseController.php:208 -msgid "Actions" -msgstr "Aktionen" - -#: src/Admin/VersionAdminController.php:148 -msgid "No versions found. Add your first version above." -msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu." - -#: src/Admin/VersionAdminController.php:165 -#: src/Admin/VersionAdminController.php:396 -msgid "Uploaded file" -msgstr "Hochgeladene Datei" - -#: src/Admin/VersionAdminController.php:169 -#: src/Admin/VersionAdminController.php:400 -msgid "No download file" -msgstr "Keine Download-Datei" - -#: src/Admin/VersionAdminController.php:182 -#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:156 -#: src/Admin/AdminController.php:907 src/Admin/AdminController.php:1232 -#: src/Admin/AdminController.php:1355 -#: src/Admin/DashboardWidgetController.php:117 -msgid "Active" -msgstr "Aktiv" - -#: src/Admin/VersionAdminController.php:182 -#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:157 -#: src/Admin/AdminController.php:914 src/Admin/AdminController.php:1233 -#: src/Admin/AdminController.php:1356 -msgid "Inactive" -msgstr "Inaktiv" - -#: src/Admin/VersionAdminController.php:188 -#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1274 -#: src/Admin/AdminController.php:1459 -msgid "Deactivate" -msgstr "Deaktivieren" - -#: src/Admin/VersionAdminController.php:188 -#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1273 -#: src/Admin/AdminController.php:1458 -msgid "Activate" -msgstr "Aktivieren" - -#: src/Admin/VersionAdminController.php:191 -#: src/Admin/VersionAdminController.php:422 src/Admin/AdminController.php:1279 -#: src/Admin/AdminController.php:1428 src/Admin/AdminController.php:1464 -msgid "Delete" -msgstr "Löschen" - -#: src/Admin/VersionAdminController.php:232 -msgid "Are you sure you want to delete this version?" -msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?" - -#: src/Admin/VersionAdminController.php:233 -msgid "Please enter a version number." -msgstr "Bitte geben Sie eine Versionsnummer ein." - -#: src/Admin/VersionAdminController.php:234 -msgid "Please enter a valid version number (e.g., 1.0.0)." -msgstr "Bitte geben Sie eine gültige Versionsnummer ein (z.B. 1.0.0)." - -#: src/Admin/VersionAdminController.php:235 -msgid "An error occurred. Please try again." -msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut." - -#: src/Admin/VersionAdminController.php:236 -msgid "Select Download File" -msgstr "Download-Datei auswählen" - -#: src/Admin/VersionAdminController.php:237 -msgid "Use this file" -msgstr "Diese Datei verwenden" - -#: src/Admin/VersionAdminController.php:238 -msgid "" -"Invalid checksum file format. File must contain a 64-character SHA256 hash." -msgstr "" -"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen SHA256-" -"Hash enthalten." - -#: src/Admin/VersionAdminController.php:239 -msgid "Failed to read checksum file." -msgstr "Prüfsummendatei konnte nicht gelesen werden." - -#: src/Admin/VersionAdminController.php:259 -#: src/Admin/VersionAdminController.php:328 -#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173 -#: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249 -#: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339 -#: src/Admin/AdminController.php:369 src/Admin/OrderLicenseController.php:387 -#: src/Admin/OrderLicenseController.php:426 -#: src/Admin/OrderLicenseController.php:490 -msgid "Permission denied." -msgstr "Zugriff verweigert." - -#: src/Admin/VersionAdminController.php:269 -msgid "Product ID and version are required." -msgstr "Produkt-ID und Version sind erforderlich." - -#: src/Admin/VersionAdminController.php:274 -msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)." -msgstr "" -"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. " -"1.0.0)." - -#: src/Admin/VersionAdminController.php:279 -msgid "This version already exists." -msgstr "Diese Version existiert bereits." - -#: src/Admin/VersionAdminController.php:285 -msgid "Product not found." -msgstr "Produkt nicht gefunden." - -#: src/Admin/VersionAdminController.php:289 -msgid "This product is not a licensed product." -msgstr "Dieses Produkt ist kein lizensiertes Produkt." - -#: src/Admin/VersionAdminController.php:306 -msgid "Failed to create version." -msgstr "Version konnte nicht erstellt werden." - -#: src/Admin/VersionAdminController.php:314 -msgid "Version added successfully." -msgstr "Version erfolgreich hinzugefügt." - -#: src/Admin/VersionAdminController.php:334 -#: src/Admin/VersionAdminController.php:361 -msgid "Version ID is required." -msgstr "Versions-ID ist erforderlich." - -#: src/Admin/VersionAdminController.php:340 -msgid "Failed to delete version." -msgstr "Version konnte nicht gelöscht werden." - -#: src/Admin/VersionAdminController.php:343 -msgid "Version deleted successfully." -msgstr "Version erfolgreich gelöscht." - -#: src/Admin/VersionAdminController.php:367 -msgid "Failed to update version." -msgstr "Version konnte nicht aktualisiert werden." - -#: src/Admin/VersionAdminController.php:371 -msgid "Version updated successfully." -msgstr "Version erfolgreich aktualisiert." - #: src/Admin/AdminController.php:76 src/Admin/AdminController.php:77 #: src/Admin/AdminController.php:90 src/Admin/AdminController.php:1200 #: src/Admin/OrderLicenseController.php:149 #: src/Admin/OrderLicenseController.php:281 -#: src/Frontend/AccountController.php:90 +#: src/Frontend/AccountController.php:91 msgid "Licenses" msgstr "Lizenzen" @@ -295,7 +66,7 @@ msgstr "Bearbeiten" #: src/Admin/AdminController.php:149 src/Admin/AdminController.php:1341 #: src/Admin/AdminController.php:1361 src/Admin/AdminController.php:1382 #: src/Admin/AdminController.php:1537 src/Admin/OrderLicenseController.php:244 -#: src/Frontend/AccountController.php:384 +#: src/Frontend/AccountController.php:387 msgid "Cancel" msgstr "Abbrechen" @@ -310,20 +81,35 @@ msgstr "Speichern" #: src/Admin/AdminController.php:1373 src/Admin/AdminController.php:1613 #: src/Admin/DashboardWidgetController.php:136 #: src/Admin/OrderLicenseController.php:260 -#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:110 +#: src/Admin/SettingsController.php:192 src/Frontend/AccountController.php:286 +#: src/Product/LicensedProductType.php:110 #: src/Product/LicensedProductType.php:158 -#: src/Frontend/AccountController.php:283 msgid "Lifetime" msgstr "Lebenslang" -#: src/Admin/AdminController.php:152 src/Frontend/AccountController.php:422 +#: src/Admin/AdminController.php:152 src/Frontend/AccountController.php:425 msgid "Copied!" msgstr "Kopiert!" -#: src/Admin/AdminController.php:153 src/Frontend/AccountController.php:423 +#: src/Admin/AdminController.php:153 src/Frontend/AccountController.php:426 msgid "Copy failed" msgstr "Kopieren fehlgeschlagen" +#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907 +#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355 +#: src/Admin/DashboardWidgetController.php:117 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 +msgid "Active" +msgstr "Aktiv" + +#: src/Admin/AdminController.php:157 src/Admin/AdminController.php:914 +#: src/Admin/AdminController.php:1233 src/Admin/AdminController.php:1356 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 +msgid "Inactive" +msgstr "Inaktiv" + #: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921 #: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357 #: src/Admin/DashboardWidgetController.php:125 @@ -336,6 +122,18 @@ msgstr "Abgelaufen" msgid "Revoked" msgstr "Widerrufen" +#: src/Admin/AdminController.php:173 src/Admin/AdminController.php:213 +#: src/Admin/AdminController.php:249 src/Admin/AdminController.php:301 +#: src/Admin/AdminController.php:339 src/Admin/AdminController.php:369 +#: src/Admin/OrderLicenseController.php:387 +#: src/Admin/OrderLicenseController.php:426 +#: src/Admin/OrderLicenseController.php:490 +#: src/Admin/VersionAdminController.php:259 +#: src/Admin/VersionAdminController.php:328 +#: src/Admin/VersionAdminController.php:354 +msgid "Permission denied." +msgstr "Zugriff verweigert." + #: src/Admin/AdminController.php:195 src/Admin/AdminController.php:1019 #: src/Admin/OrderLicenseController.php:227 msgid "Unknown" @@ -408,7 +206,7 @@ msgstr "Lizenzschlüssel und Domain sind erforderlich." #: src/Admin/AdminController.php:531 src/Admin/AdminController.php:549 #: src/Admin/AdminController.php:577 src/Admin/AdminController.php:621 #: src/Admin/AdminController.php:811 src/Admin/SettingsController.php:469 -#: src/Frontend/AccountController.php:439 +#: src/Frontend/AccountController.php:442 msgid "Security check failed." msgstr "Sicherheitsüberprüfung fehlgeschlagen." @@ -469,7 +267,7 @@ msgstr "Lizenzen verwalten" msgid "Export to CSV" msgstr "Als CSV exportieren" -#: src/Admin/AdminController.php:968 wc-licensed-product.php:137 +#: src/Admin/AdminController.php:968 msgid "Settings" msgstr "Einstellungen" @@ -636,6 +434,18 @@ msgstr "Dashboard anzeigen" msgid "Bulk Actions" msgstr "Massenaktionen" +#: src/Admin/AdminController.php:1273 src/Admin/AdminController.php:1458 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 +msgid "Activate" +msgstr "Aktivieren" + +#: src/Admin/AdminController.php:1274 src/Admin/AdminController.php:1459 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 +msgid "Deactivate" +msgstr "Deaktivieren" + #: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419 #: src/Admin/AdminController.php:1460 msgid "Revoke" @@ -653,6 +463,12 @@ msgstr "90 Tage verlängern" msgid "Extend 1 year" msgstr "1 Jahr verlängern" +#: src/Admin/AdminController.php:1279 src/Admin/AdminController.php:1428 +#: src/Admin/AdminController.php:1464 src/Admin/VersionAdminController.php:191 +#: src/Admin/VersionAdminController.php:422 +msgid "Delete" +msgstr "Löschen" + #: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466 msgid "Apply" msgstr "Anwenden" @@ -683,6 +499,12 @@ msgstr "Kunde" msgid "Domain" msgstr "Domain" +#: src/Admin/AdminController.php:1295 src/Admin/AdminController.php:1446 +#: src/Admin/OrderLicenseController.php:206 +#: src/Admin/VersionAdminController.php:140 +msgid "Status" +msgstr "Status" + #: src/Admin/AdminController.php:1296 src/Admin/AdminController.php:1447 msgid "Created" msgstr "Erstellt" @@ -694,11 +516,17 @@ msgstr "Erstellt" msgid "Expires" msgstr "Läuft ab" +#: src/Admin/AdminController.php:1298 src/Admin/AdminController.php:1449 +#: src/Admin/OrderLicenseController.php:208 +#: src/Admin/VersionAdminController.php:142 +msgid "Actions" +msgstr "Aktionen" + #: src/Admin/AdminController.php:1304 msgid "No licenses found." msgstr "Keine Lizenzen gefunden." -#: src/Admin/AdminController.php:1314 src/Frontend/AccountController.php:260 +#: src/Admin/AdminController.php:1314 src/Frontend/AccountController.php:263 msgid "Copy to clipboard" msgstr "In Zwischenablage kopieren" @@ -718,7 +546,7 @@ msgstr "Lizenz gegen API testen" msgid "Test" msgstr "Testen" -#: src/Admin/AdminController.php:1400 src/Frontend/AccountController.php:267 +#: src/Admin/AdminController.php:1400 src/Frontend/AccountController.php:270 msgid "Transfer to new domain" msgstr "Auf neue Domain übertragen" @@ -746,27 +574,27 @@ msgstr "Lizenzvalidierungstest" msgid "Testing license..." msgstr "Lizenz wird geprüft..." -#: src/Admin/AdminController.php:1508 src/Frontend/AccountController.php:362 +#: src/Admin/AdminController.php:1508 src/Frontend/AccountController.php:365 msgid "Close" msgstr "Schliessen" -#: src/Admin/AdminController.php:1517 src/Frontend/AccountController.php:363 +#: src/Admin/AdminController.php:1517 src/Frontend/AccountController.php:366 msgid "Transfer License to New Domain" msgstr "Lizenz auf neue Domain übertragen" -#: src/Admin/AdminController.php:1524 src/Frontend/AccountController.php:368 +#: src/Admin/AdminController.php:1524 src/Frontend/AccountController.php:371 msgid "Current Domain" msgstr "Aktuelle Domain" -#: src/Admin/AdminController.php:1528 src/Frontend/AccountController.php:373 +#: src/Admin/AdminController.php:1528 src/Frontend/AccountController.php:376 msgid "New Domain" msgstr "Neue Domain" -#: src/Admin/AdminController.php:1531 src/Frontend/AccountController.php:377 +#: src/Admin/AdminController.php:1531 src/Frontend/AccountController.php:380 msgid "Enter the new domain without http:// or www." msgstr "Geben Sie die neue Domain ohne http:// oder www ein." -#: src/Admin/AdminController.php:1536 src/Frontend/AccountController.php:382 +#: src/Admin/AdminController.php:1536 src/Frontend/AccountController.php:385 msgid "Transfer License" msgstr "Lizenz übertragen" @@ -774,6 +602,11 @@ msgstr "Lizenz übertragen" msgid "License is VALID" msgstr "Lizenz ist GÜLTIG" +#: src/Admin/AdminController.php:1609 src/Admin/VersionAdminController.php:81 +#: src/Admin/VersionAdminController.php:136 +msgid "Version" +msgstr "Version" + #: src/Admin/AdminController.php:1617 msgid "License is INVALID" msgstr "Lizenz ist UNGÜLTIG" @@ -956,11 +789,11 @@ msgstr "Bei der Bestellung angegebene Domains (Multi-Domain-Bestellung)." #: src/Admin/OrderLicenseController.php:119 #: src/Checkout/CheckoutController.php:436 #: src/Checkout/CheckoutController.php:486 -#: src/Checkout/CheckoutController.php:496 src/License/LicenseManager.php:806 -#: src/Product/VersionManager.php:349 src/Product/VersionManager.php:361 -#: src/Frontend/AccountController.php:146 +#: src/Checkout/CheckoutController.php:496 #: src/Email/LicenseExpirationEmail.php:107 -#: src/Email/LicenseExpiredEmail.php:99 +#: src/Email/LicenseExpiredEmail.php:99 src/Frontend/AccountController.php:148 +#: src/License/LicenseManager.php:806 src/Product/VersionManager.php:349 +#: src/Product/VersionManager.php:361 msgid "Unknown Product" msgstr "Unbekanntes Produkt" @@ -1045,8 +878,8 @@ msgstr "Fehler. Bitte versuchen Sie es erneut." #: src/Admin/OrderLicenseController.php:373 #: src/Checkout/CheckoutBlocksIntegration.php:126 -#: src/Frontend/AccountController.php:427 -#: src/Frontend/AccountController.php:459 +#: src/Frontend/AccountController.php:430 +#: src/Frontend/AccountController.php:462 msgid "Please enter a valid domain." msgstr "Bitte geben Sie eine gültige Domain ein." @@ -1069,8 +902,8 @@ msgid "Order domain updated." msgstr "Bestellungs-Domain aktualisiert." #: src/Admin/OrderLicenseController.php:449 +#: src/Frontend/AccountController.php:468 #: src/Frontend/DownloadController.php:117 -#: src/Frontend/AccountController.php:465 msgid "License not found." msgstr "Lizenz nicht gefunden." @@ -1280,6 +1113,176 @@ msgstr "Lizenz erfolgreich überprüft!" msgid "License validation failed." msgstr "Lizenzvalidierung fehlgeschlagen." +#: src/Admin/VersionAdminController.php:58 +msgid "Product Versions" +msgstr "Produktversionen" + +#: src/Admin/VersionAdminController.php:78 +msgid "Add New Version" +msgstr "Neue Version hinzufügen" + +#: src/Admin/VersionAdminController.php:84 +msgid "Use semantic versioning (e.g., 1.0.0)" +msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)" + +#: src/Admin/VersionAdminController.php:88 +#: src/Admin/VersionAdminController.php:137 +msgid "Download File" +msgstr "Download-Datei" + +#: src/Admin/VersionAdminController.php:93 +msgid "Select File" +msgstr "Datei auswählen" + +#: src/Admin/VersionAdminController.php:96 +#: src/Admin/VersionAdminController.php:110 +msgid "Remove" +msgstr "Entfernen" + +#: src/Admin/VersionAdminController.php:98 +msgid "" +"Upload or select a file from the media library. Version will be auto-" +"detected from filename (e.g., plugin-v1.2.3.zip)." +msgstr "" +"Laden Sie eine Datei hoch oder wählen Sie eine aus der Mediathek. Die " +"Version wird automatisch aus dem Dateinamen erkannt (z.B. plugin-v1.2.3.zip)." + +#: src/Admin/VersionAdminController.php:102 +msgid "Checksum File" +msgstr "Prüfsummendatei" + +#: src/Admin/VersionAdminController.php:107 +msgid "Select Checksum File" +msgstr "Prüfsummendatei auswählen" + +#: src/Admin/VersionAdminController.php:112 +msgid "" +"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity." +msgstr "" +"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die " +"Dateiintegrität zu überprüfen." + +#: src/Admin/VersionAdminController.php:116 +#: src/Admin/VersionAdminController.php:139 +msgid "Release Notes" +msgstr "Versionshinweise" + +#: src/Admin/VersionAdminController.php:124 +msgid "Add Version" +msgstr "Version hinzufügen" + +#: src/Admin/VersionAdminController.php:132 +msgid "Existing Versions" +msgstr "Vorhandene Versionen" + +#: src/Admin/VersionAdminController.php:138 +msgid "SHA256" +msgstr "SHA256" + +#: src/Admin/VersionAdminController.php:141 +msgid "Released" +msgstr "Veröffentlicht" + +#: src/Admin/VersionAdminController.php:148 +msgid "No versions found. Add your first version above." +msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu." + +#: src/Admin/VersionAdminController.php:165 +#: src/Admin/VersionAdminController.php:396 +msgid "Uploaded file" +msgstr "Hochgeladene Datei" + +#: src/Admin/VersionAdminController.php:169 +#: src/Admin/VersionAdminController.php:400 +msgid "No download file" +msgstr "Keine Download-Datei" + +#: src/Admin/VersionAdminController.php:232 +msgid "Are you sure you want to delete this version?" +msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?" + +#: src/Admin/VersionAdminController.php:233 +msgid "Please enter a version number." +msgstr "Bitte geben Sie eine Versionsnummer ein." + +#: src/Admin/VersionAdminController.php:234 +msgid "Please enter a valid version number (e.g., 1.0.0)." +msgstr "Bitte geben Sie eine gültige Versionsnummer ein (z.B. 1.0.0)." + +#: src/Admin/VersionAdminController.php:235 +msgid "An error occurred. Please try again." +msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut." + +#: src/Admin/VersionAdminController.php:236 +msgid "Select Download File" +msgstr "Download-Datei auswählen" + +#: src/Admin/VersionAdminController.php:237 +msgid "Use this file" +msgstr "Diese Datei verwenden" + +#: src/Admin/VersionAdminController.php:238 +msgid "" +"Invalid checksum file format. File must contain a 64-character SHA256 hash." +msgstr "" +"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen SHA256-" +"Hash enthalten." + +#: src/Admin/VersionAdminController.php:239 +msgid "Failed to read checksum file." +msgstr "Prüfsummendatei konnte nicht gelesen werden." + +#: src/Admin/VersionAdminController.php:269 +msgid "Product ID and version are required." +msgstr "Produkt-ID und Version sind erforderlich." + +#: src/Admin/VersionAdminController.php:274 +msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)." +msgstr "" +"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. " +"1.0.0)." + +#: src/Admin/VersionAdminController.php:279 +msgid "This version already exists." +msgstr "Diese Version existiert bereits." + +#: src/Admin/VersionAdminController.php:285 +msgid "Product not found." +msgstr "Produkt nicht gefunden." + +#: src/Admin/VersionAdminController.php:289 +msgid "This product is not a licensed product." +msgstr "Dieses Produkt ist kein lizensiertes Produkt." + +#: src/Admin/VersionAdminController.php:306 +msgid "Failed to create version." +msgstr "Version konnte nicht erstellt werden." + +#: src/Admin/VersionAdminController.php:314 +msgid "Version added successfully." +msgstr "Version erfolgreich hinzugefügt." + +#: src/Admin/VersionAdminController.php:334 +#: src/Admin/VersionAdminController.php:361 +msgid "Version ID is required." +msgstr "Versions-ID ist erforderlich." + +#: src/Admin/VersionAdminController.php:340 +msgid "Failed to delete version." +msgstr "Version konnte nicht gelöscht werden." + +#: src/Admin/VersionAdminController.php:343 +msgid "Version deleted successfully." +msgstr "Version erfolgreich gelöscht." + +#: src/Admin/VersionAdminController.php:367 +msgid "Failed to update version." +msgstr "Version konnte nicht aktualisiert werden." + +#: src/Admin/VersionAdminController.php:371 +msgid "Version updated successfully." +msgstr "Version erfolgreich aktualisiert." + #: src/Api/RestApiController.php:84 msgid "Too many requests. Please try again later." msgstr "Zu viele Anfragen. Bitte versuchen Sie es später erneut." @@ -1400,231 +1403,56 @@ msgstr "Domains für Lizenz-Aktivierung nach Produkt" msgid "Domain for license activation" msgstr "Domain für Lizenz-Aktivierung" -#: src/License/PluginLicenseChecker.php:132 -msgid "License settings not configured." -msgstr "Lizenzeinstellungen nicht konfiguriert." +#: src/Email/LicenseEmailController.php:212 +#: src/Email/LicenseEmailController.php:220 +msgid "License Keys:" +msgstr "Lizenzschlüssel:" -#: src/License/PluginLicenseChecker.php:168 -msgid "Could not connect to license server." -msgstr "Verbindung zum Lizenzserver konnte nicht hergestellt werden." +#: src/Email/LicenseEmailController.php:268 +msgid "Your License Keys" +msgstr "Ihre Lizenzschlüssel" -#: src/License/LicenseManager.php:412 -msgid "This license has been revoked." -msgstr "Diese Lizenz wurde widerrufen." - -#: src/License/LicenseManager.php:422 -msgid "This license has expired." -msgstr "Diese Lizenz ist abgelaufen." - -#: src/License/LicenseManager.php:430 -msgid "This license is inactive." -msgstr "Diese Lizenz ist inaktiv." - -#: src/License/LicenseManager.php:440 -msgid "This license is not valid for this domain." -msgstr "Diese Lizenz ist für diese Domain nicht gültig." - -#: src/Product/LicensedProductType.php:61 -msgid "Licensed Product" -msgstr "Lizensiertes Produkt" - -#: src/Product/LicensedProductType.php:82 -msgid "License Settings" -msgstr "Lizenz-Einstellungen" - -#: src/Product/LicensedProductType.php:109 +#: src/Email/LicenseEmailController.php:277 #, php-format -msgid "%d days" -msgstr "%d Tage" +msgid "%d license" +msgid_plural "%d licenses" +msgstr[0] "%d Lizenz" +msgstr[1] "%d Lizenzen" -#: src/Product/LicensedProductType.php:119 -#, php-format -msgid "Leave fields empty to use default settings from %s." -msgstr "Felder leer lassen, um Standardeinstellungen von %s zu verwenden." +#: src/Email/LicenseEmailController.php:308 +#: src/Email/LicenseEmailController.php:352 +msgid "Never" +msgstr "Nie" -#: src/Product/LicensedProductType.php:121 -msgid "WooCommerce > Settings > Licensed Products" -msgstr "WooCommerce > Einstellungen > Lizensierte Produkte" - -#: src/Product/LicensedProductType.php:128 -msgid "Max Activations" -msgstr "Max. Aktivierungen" - -#: src/Product/LicensedProductType.php:131 -#, php-format -msgid "Maximum number of domain activations per license. Default: %d" -msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d" - -#: src/Product/LicensedProductType.php:146 -msgid "License Validity (Days)" -msgstr "Lizenz-Gültigkeit (Tage)" - -#: src/Product/LicensedProductType.php:149 -#, php-format -msgid "Number of days the license is valid. Leave empty for default (%s)." -msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s)." - -#: src/Product/LicensedProductType.php:164 -msgid "Bind to Major Version" -msgstr "An Hauptversion binden" - -#: src/Product/LicensedProductType.php:167 -#, php-format -msgid "" -"If enabled, licenses are bound to the major version at purchase time. " -"Default: %s" +#: src/Email/LicenseEmailController.php:319 +#: src/Email/LicenseEmailController.php:357 +msgid "You can also view your licenses in your account under \"Licenses\"." msgstr "" -"Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt " -"gebunden. Standard: %s" +"Sie können Ihre Lizenzen auch in Ihrem Konto unter \"Lizenzen\" einsehen." -#: src/Product/LicensedProductType.php:168 -msgid "Yes" -msgstr "Ja" +#: src/Email/LicenseEmailController.php:332 +msgid "YOUR LICENSE KEYS" +msgstr "IHRE LIZENZSCHLÜSSEL" -#: src/Product/LicensedProductType.php:168 -msgid "No" -msgstr "Nein" +#: src/Email/LicenseEmailController.php:343 +#: src/Email/LicenseExpirationEmail.php:207 +#: src/Email/LicenseExpirationEmail.php:270 +#: src/Email/LicenseExpiredEmail.php:191 src/Email/LicenseExpiredEmail.php:256 +msgid "License Key:" +msgstr "Lizenzschlüssel:" -#: src/Product/LicensedProductType.php:288 -msgid "Version:" -msgstr "Version:" +#: src/Email/LicenseEmailController.php:345 +#: src/Email/LicenseExpirationEmail.php:215 +#: src/Email/LicenseExpirationEmail.php:271 +#: src/Email/LicenseExpiredEmail.php:199 src/Email/LicenseExpiredEmail.php:257 +msgid "Domain:" +msgstr "Domain:" -#: src/Product/VersionManager.php:166 -msgid "Attachment file not found." -msgstr "Anhangs-Datei nicht gefunden." - -#: src/Product/VersionManager.php:177 -#, php-format -msgid "File checksum does not match. Expected: %1$s, Got: %2$s" -msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s" - -#: src/Frontend/DownloadController.php:77 -#: src/Frontend/DownloadController.php:101 -msgid "Invalid download link." -msgstr "Ungültiger Download-Link." - -#: src/Frontend/DownloadController.php:78 -#: src/Frontend/DownloadController.php:88 -#: src/Frontend/DownloadController.php:102 -#: src/Frontend/DownloadController.php:118 -#: src/Frontend/DownloadController.php:128 -#: src/Frontend/DownloadController.php:137 -#: src/Frontend/DownloadController.php:147 -#: src/Frontend/DownloadController.php:156 -#: src/Frontend/DownloadController.php:165 -#: src/Frontend/DownloadController.php:187 -#: src/Frontend/DownloadController.php:203 -msgid "Download Error" -msgstr "Download-Fehler" - -#: src/Frontend/DownloadController.php:87 -msgid "Invalid download link format." -msgstr "Ungültiges Download-Link-Format." - -#: src/Frontend/DownloadController.php:127 -msgid "You do not have permission to download this file." -msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen." - -#: src/Frontend/DownloadController.php:136 -msgid "Your license is not active. Please contact support." -msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support." - -#: src/Frontend/DownloadController.php:146 -msgid "Version not found." -msgstr "Version nicht gefunden." - -#: src/Frontend/DownloadController.php:155 -msgid "Version does not match your licensed product." -msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein." - -#: src/Frontend/DownloadController.php:164 -msgid "This version is no longer available for download." -msgstr "Diese Version ist nicht mehr zum Download verfügbar." - -#: src/Frontend/DownloadController.php:186 -msgid "No download file available for this version." -msgstr "Keine Download-Datei für diese Version verfügbar." - -#: src/Frontend/DownloadController.php:202 -msgid "Download file not found." -msgstr "Download-Datei nicht gefunden." - -#: src/Frontend/AccountController.php:104 -msgid "Please log in to view your licenses." -msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen." - -#: src/Frontend/AccountController.php:220 -msgid "You have no licenses yet." -msgstr "Sie haben noch keine Lizenzen." - -#: src/Frontend/AccountController.php:242 -#, php-format -msgid "Order #%s" -msgstr "Bestellung #%s" - -#: src/Frontend/AccountController.php:293 -msgid "Available Downloads" -msgstr "Verfügbare Downloads" - -#: src/Frontend/AccountController.php:302 -#: src/Frontend/AccountController.php:335 -#, php-format -msgid "Version %s" -msgstr "Version %s" - -#: src/Frontend/AccountController.php:304 -msgid "Latest" -msgstr "Neueste" - -#: src/Frontend/AccountController.php:324 -#, php-format -msgid "Older versions (%d)" -msgstr "Ältere Versionen (%d)" - -#: src/Frontend/AccountController.php:424 -#: src/Frontend/AccountController.php:491 -msgid "License transferred successfully!" -msgstr "Lizenz erfolgreich übertragen!" - -#: src/Frontend/AccountController.php:425 -msgid "Transfer failed. Please try again." -msgstr "Übertragung fehlgeschlagen. Bitte versuchen Sie es erneut." - -#: src/Frontend/AccountController.php:426 -msgid "" -"Are you sure you want to transfer this license to a new domain? This action " -"cannot be undone." -msgstr "" -"Sind Sie sicher, dass Sie diese Lizenz auf eine neue Domain übertragen " -"möchten? Diese Aktion kann nicht rückgängig gemacht werden." - -#: src/Frontend/AccountController.php:445 -msgid "Please log in to transfer a license." -msgstr "Bitte melden Sie sich an, um eine Lizenz zu übertragen." - -#: src/Frontend/AccountController.php:451 -msgid "Invalid license." -msgstr "Ungültige Lizenz." - -#: src/Frontend/AccountController.php:469 -msgid "You do not have permission to transfer this license." -msgstr "Sie haben keine Berechtigung, diese Lizenz zu übertragen." - -#: src/Frontend/AccountController.php:474 -msgid "Revoked licenses cannot be transferred." -msgstr "Widerrufene Lizenzen können nicht übertragen werden." - -#: src/Frontend/AccountController.php:478 -msgid "Expired licenses cannot be transferred." -msgstr "Abgelaufene Lizenzen können nicht übertragen werden." - -#: src/Frontend/AccountController.php:483 -msgid "The new domain is the same as the current domain." -msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain." - -#: src/Frontend/AccountController.php:495 -msgid "Failed to transfer license. Please try again." -msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut." +#: src/Email/LicenseEmailController.php:347 +#: src/Email/LicenseExpirationEmail.php:219 +#: src/Email/LicenseExpirationEmail.php:272 +msgid "Expires:" +msgstr "Läuft ab:" #: src/Email/LicenseExpirationEmail.php:55 msgid "License Expiration Warning" @@ -1680,26 +1508,6 @@ msgstr "Lizenzdetails" msgid "Product:" msgstr "Produkt:" -#: src/Email/LicenseExpirationEmail.php:207 -#: src/Email/LicenseExpirationEmail.php:270 -#: src/Email/LicenseExpiredEmail.php:191 src/Email/LicenseExpiredEmail.php:256 -#: src/Email/LicenseEmailController.php:343 -msgid "License Key:" -msgstr "Lizenzschlüssel:" - -#: src/Email/LicenseExpirationEmail.php:215 -#: src/Email/LicenseExpirationEmail.php:271 -#: src/Email/LicenseExpiredEmail.php:199 src/Email/LicenseExpiredEmail.php:257 -#: src/Email/LicenseEmailController.php:345 -msgid "Domain:" -msgstr "Domain:" - -#: src/Email/LicenseExpirationEmail.php:219 -#: src/Email/LicenseExpirationEmail.php:272 -#: src/Email/LicenseEmailController.php:347 -msgid "Expires:" -msgstr "Läuft ab:" - #: src/Email/LicenseExpirationEmail.php:235 #: src/Email/LicenseExpirationEmail.php:281 #: src/Email/LicenseExpiredEmail.php:227 src/Email/LicenseExpiredEmail.php:268 @@ -1806,36 +1614,157 @@ msgid "To continue using this product, please renew your license." msgstr "" "Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz." -#: src/Email/LicenseEmailController.php:212 -#: src/Email/LicenseEmailController.php:220 -msgid "License Keys:" -msgstr "Lizenzschlüssel:" +#: src/Frontend/AccountController.php:105 +msgid "Please log in to view your licenses." +msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen." -#: src/Email/LicenseEmailController.php:268 -msgid "Your License Keys" -msgstr "Ihre Lizenzschlüssel" +#: src/Frontend/AccountController.php:223 +msgid "You have no licenses yet." +msgstr "Sie haben noch keine Lizenzen." -#: src/Email/LicenseEmailController.php:277 +#: src/Frontend/AccountController.php:245 #, php-format -msgid "%d license" -msgid_plural "%d licenses" -msgstr[0] "%d Lizenz" -msgstr[1] "%d Lizenzen" +msgid "Order #%s" +msgstr "Bestellung #%s" -#: src/Email/LicenseEmailController.php:308 -#: src/Email/LicenseEmailController.php:352 -msgid "Never" -msgstr "Nie" +#: src/Frontend/AccountController.php:296 +msgid "Available Downloads" +msgstr "Verfügbare Downloads" -#: src/Email/LicenseEmailController.php:319 -#: src/Email/LicenseEmailController.php:357 -msgid "You can also view your licenses in your account under \"Licenses\"." +#: src/Frontend/AccountController.php:305 +#: src/Frontend/AccountController.php:338 +#, php-format +msgid "Version %s" +msgstr "Version %s" + +#: src/Frontend/AccountController.php:307 +msgid "Latest" +msgstr "Neueste" + +#: src/Frontend/AccountController.php:327 +#, php-format +msgid "Older versions (%d)" +msgstr "Ältere Versionen (%d)" + +#: src/Frontend/AccountController.php:427 +#: src/Frontend/AccountController.php:494 +msgid "License transferred successfully!" +msgstr "Lizenz erfolgreich übertragen!" + +#: src/Frontend/AccountController.php:428 +msgid "Transfer failed. Please try again." +msgstr "Übertragung fehlgeschlagen. Bitte versuchen Sie es erneut." + +#: src/Frontend/AccountController.php:429 +msgid "" +"Are you sure you want to transfer this license to a new domain? This action " +"cannot be undone." msgstr "" -"Sie können Ihre Lizenzen auch in Ihrem Konto unter \"Lizenzen\" einsehen." +"Sind Sie sicher, dass Sie diese Lizenz auf eine neue Domain übertragen " +"möchten? Diese Aktion kann nicht rückgängig gemacht werden." -#: src/Email/LicenseEmailController.php:332 -msgid "YOUR LICENSE KEYS" -msgstr "IHRE LIZENZSCHLÜSSEL" +#: src/Frontend/AccountController.php:448 +msgid "Please log in to transfer a license." +msgstr "Bitte melden Sie sich an, um eine Lizenz zu übertragen." + +#: src/Frontend/AccountController.php:454 +msgid "Invalid license." +msgstr "Ungültige Lizenz." + +#: src/Frontend/AccountController.php:472 +msgid "You do not have permission to transfer this license." +msgstr "Sie haben keine Berechtigung, diese Lizenz zu übertragen." + +#: src/Frontend/AccountController.php:477 +msgid "Revoked licenses cannot be transferred." +msgstr "Widerrufene Lizenzen können nicht übertragen werden." + +#: src/Frontend/AccountController.php:481 +msgid "Expired licenses cannot be transferred." +msgstr "Abgelaufene Lizenzen können nicht übertragen werden." + +#: src/Frontend/AccountController.php:486 +msgid "The new domain is the same as the current domain." +msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain." + +#: src/Frontend/AccountController.php:498 +msgid "Failed to transfer license. Please try again." +msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut." + +#: src/Frontend/DownloadController.php:77 +#: src/Frontend/DownloadController.php:101 +msgid "Invalid download link." +msgstr "Ungültiger Download-Link." + +#: src/Frontend/DownloadController.php:78 +#: src/Frontend/DownloadController.php:88 +#: src/Frontend/DownloadController.php:102 +#: src/Frontend/DownloadController.php:118 +#: src/Frontend/DownloadController.php:128 +#: src/Frontend/DownloadController.php:137 +#: src/Frontend/DownloadController.php:147 +#: src/Frontend/DownloadController.php:156 +#: src/Frontend/DownloadController.php:165 +#: src/Frontend/DownloadController.php:187 +#: src/Frontend/DownloadController.php:203 +msgid "Download Error" +msgstr "Download-Fehler" + +#: src/Frontend/DownloadController.php:87 +msgid "Invalid download link format." +msgstr "Ungültiges Download-Link-Format." + +#: src/Frontend/DownloadController.php:127 +msgid "You do not have permission to download this file." +msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen." + +#: src/Frontend/DownloadController.php:136 +msgid "Your license is not active. Please contact support." +msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support." + +#: src/Frontend/DownloadController.php:146 +msgid "Version not found." +msgstr "Version nicht gefunden." + +#: src/Frontend/DownloadController.php:155 +msgid "Version does not match your licensed product." +msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein." + +#: src/Frontend/DownloadController.php:164 +msgid "This version is no longer available for download." +msgstr "Diese Version ist nicht mehr zum Download verfügbar." + +#: src/Frontend/DownloadController.php:186 +msgid "No download file available for this version." +msgstr "Keine Download-Datei für diese Version verfügbar." + +#: src/Frontend/DownloadController.php:202 +msgid "Download file not found." +msgstr "Download-Datei nicht gefunden." + +#: src/License/LicenseManager.php:412 +msgid "This license has been revoked." +msgstr "Diese Lizenz wurde widerrufen." + +#: src/License/LicenseManager.php:422 +msgid "This license has expired." +msgstr "Diese Lizenz ist abgelaufen." + +#: src/License/LicenseManager.php:430 +msgid "This license is inactive." +msgstr "Diese Lizenz ist inaktiv." + +#: src/License/LicenseManager.php:440 +msgid "This license is not valid for this domain." +msgstr "Diese Lizenz ist für diese Domain nicht gültig." + +#: src/License/PluginLicenseChecker.php:132 +msgid "License settings not configured." +msgstr "Lizenzeinstellungen nicht konfiguriert." + +#: src/License/PluginLicenseChecker.php:168 +msgid "Could not connect to license server." +msgstr "Verbindung zum Lizenzserver konnte nicht hergestellt werden." #: src/Plugin.php:318 msgid "WC Licensed Product" @@ -1852,16 +1781,97 @@ msgstr "" msgid "Configure License" msgstr "Lizenz konfigurieren" -#: wc-licensed-product.php:61 -#, php-format -msgid "%s requires WooCommerce to be installed and active." -msgstr "%s benötigt WooCommerce als installierte und aktivierte Erweiterung." +#: src/Product/LicensedProductType.php:61 +msgid "Licensed Product" +msgstr "Lizensiertes Produkt" -#: wc-licensed-product.php:119 -msgid "WC Licensed Product requires WooCommerce to be installed and active." +#: src/Product/LicensedProductType.php:82 +msgid "License Settings" +msgstr "Lizenz-Einstellungen" + +#: src/Product/LicensedProductType.php:109 +#, php-format +msgid "%d days" +msgstr "%d Tage" + +#: src/Product/LicensedProductType.php:119 +#, php-format +msgid "Leave fields empty to use default settings from %s." +msgstr "Felder leer lassen, um Standardeinstellungen von %s zu verwenden." + +#: src/Product/LicensedProductType.php:121 +msgid "WooCommerce > Settings > Licensed Products" +msgstr "WooCommerce > Einstellungen > Lizensierte Produkte" + +#: src/Product/LicensedProductType.php:128 +msgid "Max Activations" +msgstr "Max. Aktivierungen" + +#: src/Product/LicensedProductType.php:131 +#, php-format +msgid "Maximum number of domain activations per license. Default: %d" +msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d" + +#: src/Product/LicensedProductType.php:146 +msgid "License Validity (Days)" +msgstr "Lizenz-Gültigkeit (Tage)" + +#: src/Product/LicensedProductType.php:149 +#, php-format +msgid "Number of days the license is valid. Leave empty for default (%s)." +msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s)." + +#: src/Product/LicensedProductType.php:164 +msgid "Bind to Major Version" +msgstr "An Hauptversion binden" + +#: src/Product/LicensedProductType.php:167 +#, php-format +msgid "" +"If enabled, licenses are bound to the major version at purchase time. " +"Default: %s" msgstr "" -"WC Licensed Product benötigt WooCommerce als installierte und aktivierte " -"Erweiterung." +"Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt " +"gebunden. Standard: %s" + +#: src/Product/LicensedProductType.php:168 +msgid "Yes" +msgstr "Ja" + +#: src/Product/LicensedProductType.php:168 +msgid "No" +msgstr "Nein" + +#: src/Product/LicensedProductType.php:288 +msgid "Version:" +msgstr "Version:" + +#: src/Product/VersionManager.php:166 +msgid "Attachment file not found." +msgstr "Anhangs-Datei nicht gefunden." + +#: src/Product/VersionManager.php:177 +#, php-format +msgid "File checksum does not match. Expected: %1$s, Got: %2$s" +msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s" + +#: templates/frontend/licenses.html.twig:72 +msgid "API Verification Secret" +msgstr "API-Verifizierungs-Secret" + +#: templates/frontend/licenses.html.twig:77 +msgid "Use this secret to verify signed API responses. Keep it secure." +msgstr "Verwenden Sie dieses Secret, um signierte API-Antworten zu verifizieren. Bewahren Sie es sicher auf." + +#, php-format +#~ msgid "%s requires WooCommerce to be installed and active." +#~ msgstr "" +#~ "%s benötigt WooCommerce als installierte und aktivierte Erweiterung." + +#~ msgid "WC Licensed Product requires WooCommerce to be installed and active." +#~ msgstr "" +#~ "WC Licensed Product benötigt WooCommerce als installierte und aktivierte " +#~ "Erweiterung." #~ msgid "Domain for License Activation" #~ msgstr "Domain für Lizenz-Aktivierung" diff --git a/languages/wc-licensed-product.pot b/languages/wc-licensed-product.pot index 62b7f9d..2a17887 100644 --- a/languages/wc-licensed-product.pot +++ b/languages/wc-licensed-product.pot @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# This file is distributed under the same license as the WC Licensed Product package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-25 18:32+0100\n" +"Project-Id-Version: WC Licensed Product 0.5.1\n" +"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" +"POT-Creation-Date: 2026-01-26 15:26+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,232 +18,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: src/Admin/VersionAdminController.php:58 -msgid "Product Versions" -msgstr "" - -#: src/Admin/VersionAdminController.php:78 -msgid "Add New Version" -msgstr "" - -#: src/Admin/VersionAdminController.php:81 -#: src/Admin/VersionAdminController.php:136 src/Admin/AdminController.php:1609 -msgid "Version" -msgstr "" - -#: src/Admin/VersionAdminController.php:84 -msgid "Use semantic versioning (e.g., 1.0.0)" -msgstr "" - -#: src/Admin/VersionAdminController.php:88 -#: src/Admin/VersionAdminController.php:137 -msgid "Download File" -msgstr "" - -#: src/Admin/VersionAdminController.php:93 -msgid "Select File" -msgstr "" - -#: src/Admin/VersionAdminController.php:96 -#: src/Admin/VersionAdminController.php:110 -msgid "Remove" -msgstr "" - -#: src/Admin/VersionAdminController.php:98 -msgid "" -"Upload or select a file from the media library. Version will be auto-" -"detected from filename (e.g., plugin-v1.2.3.zip)." -msgstr "" - -#: src/Admin/VersionAdminController.php:102 -msgid "Checksum File" -msgstr "" - -#: src/Admin/VersionAdminController.php:107 -msgid "Select Checksum File" -msgstr "" - -#: src/Admin/VersionAdminController.php:112 -msgid "" -"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity." -msgstr "" - -#: src/Admin/VersionAdminController.php:116 -#: src/Admin/VersionAdminController.php:139 -msgid "Release Notes" -msgstr "" - -#: src/Admin/VersionAdminController.php:124 -msgid "Add Version" -msgstr "" - -#: src/Admin/VersionAdminController.php:132 -msgid "Existing Versions" -msgstr "" - -#: src/Admin/VersionAdminController.php:138 -msgid "SHA256" -msgstr "" - -#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 -#: src/Admin/AdminController.php:1446 src/Admin/OrderLicenseController.php:206 -msgid "Status" -msgstr "" - -#: src/Admin/VersionAdminController.php:141 -msgid "Released" -msgstr "" - -#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 -#: src/Admin/AdminController.php:1449 src/Admin/OrderLicenseController.php:208 -msgid "Actions" -msgstr "" - -#: src/Admin/VersionAdminController.php:148 -msgid "No versions found. Add your first version above." -msgstr "" - -#: src/Admin/VersionAdminController.php:165 -#: src/Admin/VersionAdminController.php:396 -msgid "Uploaded file" -msgstr "" - -#: src/Admin/VersionAdminController.php:169 -#: src/Admin/VersionAdminController.php:400 -msgid "No download file" -msgstr "" - -#: src/Admin/VersionAdminController.php:182 -#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:156 -#: src/Admin/AdminController.php:907 src/Admin/AdminController.php:1232 -#: src/Admin/AdminController.php:1355 -#: src/Admin/DashboardWidgetController.php:117 -msgid "Active" -msgstr "" - -#: src/Admin/VersionAdminController.php:182 -#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:157 -#: src/Admin/AdminController.php:914 src/Admin/AdminController.php:1233 -#: src/Admin/AdminController.php:1356 -msgid "Inactive" -msgstr "" - -#: src/Admin/VersionAdminController.php:188 -#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1274 -#: src/Admin/AdminController.php:1459 -msgid "Deactivate" -msgstr "" - -#: src/Admin/VersionAdminController.php:188 -#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1273 -#: src/Admin/AdminController.php:1458 -msgid "Activate" -msgstr "" - -#: src/Admin/VersionAdminController.php:191 -#: src/Admin/VersionAdminController.php:422 src/Admin/AdminController.php:1279 -#: src/Admin/AdminController.php:1428 src/Admin/AdminController.php:1464 -msgid "Delete" -msgstr "" - -#: src/Admin/VersionAdminController.php:232 -msgid "Are you sure you want to delete this version?" -msgstr "" - -#: src/Admin/VersionAdminController.php:233 -msgid "Please enter a version number." -msgstr "" - -#: src/Admin/VersionAdminController.php:234 -msgid "Please enter a valid version number (e.g., 1.0.0)." -msgstr "" - -#: src/Admin/VersionAdminController.php:235 -msgid "An error occurred. Please try again." -msgstr "" - -#: src/Admin/VersionAdminController.php:236 -msgid "Select Download File" -msgstr "" - -#: src/Admin/VersionAdminController.php:237 -msgid "Use this file" -msgstr "" - -#: src/Admin/VersionAdminController.php:238 -msgid "" -"Invalid checksum file format. File must contain a 64-character SHA256 hash." -msgstr "" - -#: src/Admin/VersionAdminController.php:239 -msgid "Failed to read checksum file." -msgstr "" - -#: src/Admin/VersionAdminController.php:259 -#: src/Admin/VersionAdminController.php:328 -#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173 -#: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249 -#: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339 -#: src/Admin/AdminController.php:369 src/Admin/OrderLicenseController.php:387 -#: src/Admin/OrderLicenseController.php:426 -#: src/Admin/OrderLicenseController.php:490 -msgid "Permission denied." -msgstr "" - -#: src/Admin/VersionAdminController.php:269 -msgid "Product ID and version are required." -msgstr "" - -#: src/Admin/VersionAdminController.php:274 -msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)." -msgstr "" - -#: src/Admin/VersionAdminController.php:279 -msgid "This version already exists." -msgstr "" - -#: src/Admin/VersionAdminController.php:285 -msgid "Product not found." -msgstr "" - -#: src/Admin/VersionAdminController.php:289 -msgid "This product is not a licensed product." -msgstr "" - -#: src/Admin/VersionAdminController.php:306 -msgid "Failed to create version." -msgstr "" - -#: src/Admin/VersionAdminController.php:314 -msgid "Version added successfully." -msgstr "" - -#: src/Admin/VersionAdminController.php:334 -#: src/Admin/VersionAdminController.php:361 -msgid "Version ID is required." -msgstr "" - -#: src/Admin/VersionAdminController.php:340 -msgid "Failed to delete version." -msgstr "" - -#: src/Admin/VersionAdminController.php:343 -msgid "Version deleted successfully." -msgstr "" - -#: src/Admin/VersionAdminController.php:367 -msgid "Failed to update version." -msgstr "" - -#: src/Admin/VersionAdminController.php:371 -msgid "Version updated successfully." -msgstr "" - #: src/Admin/AdminController.php:76 src/Admin/AdminController.php:77 #: src/Admin/AdminController.php:90 src/Admin/AdminController.php:1200 #: src/Admin/OrderLicenseController.php:149 #: src/Admin/OrderLicenseController.php:281 -#: src/Frontend/AccountController.php:90 +#: src/Frontend/AccountController.php:91 msgid "Licenses" msgstr "" @@ -288,7 +67,7 @@ msgstr "" #: src/Admin/AdminController.php:149 src/Admin/AdminController.php:1341 #: src/Admin/AdminController.php:1361 src/Admin/AdminController.php:1382 #: src/Admin/AdminController.php:1537 src/Admin/OrderLicenseController.php:244 -#: src/Frontend/AccountController.php:384 +#: src/Frontend/AccountController.php:387 msgid "Cancel" msgstr "" @@ -303,20 +82,35 @@ msgstr "" #: src/Admin/AdminController.php:1373 src/Admin/AdminController.php:1613 #: src/Admin/DashboardWidgetController.php:136 #: src/Admin/OrderLicenseController.php:260 -#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:110 +#: src/Admin/SettingsController.php:192 src/Frontend/AccountController.php:286 +#: src/Product/LicensedProductType.php:110 #: src/Product/LicensedProductType.php:158 -#: src/Frontend/AccountController.php:283 msgid "Lifetime" msgstr "" -#: src/Admin/AdminController.php:152 src/Frontend/AccountController.php:422 +#: src/Admin/AdminController.php:152 src/Frontend/AccountController.php:425 msgid "Copied!" msgstr "" -#: src/Admin/AdminController.php:153 src/Frontend/AccountController.php:423 +#: src/Admin/AdminController.php:153 src/Frontend/AccountController.php:426 msgid "Copy failed" msgstr "" +#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907 +#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355 +#: src/Admin/DashboardWidgetController.php:117 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 +msgid "Active" +msgstr "" + +#: src/Admin/AdminController.php:157 src/Admin/AdminController.php:914 +#: src/Admin/AdminController.php:1233 src/Admin/AdminController.php:1356 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 +msgid "Inactive" +msgstr "" + #: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921 #: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357 #: src/Admin/DashboardWidgetController.php:125 @@ -329,6 +123,18 @@ msgstr "" msgid "Revoked" msgstr "" +#: src/Admin/AdminController.php:173 src/Admin/AdminController.php:213 +#: src/Admin/AdminController.php:249 src/Admin/AdminController.php:301 +#: src/Admin/AdminController.php:339 src/Admin/AdminController.php:369 +#: src/Admin/OrderLicenseController.php:387 +#: src/Admin/OrderLicenseController.php:426 +#: src/Admin/OrderLicenseController.php:490 +#: src/Admin/VersionAdminController.php:259 +#: src/Admin/VersionAdminController.php:328 +#: src/Admin/VersionAdminController.php:354 +msgid "Permission denied." +msgstr "" + #: src/Admin/AdminController.php:195 src/Admin/AdminController.php:1019 #: src/Admin/OrderLicenseController.php:227 msgid "Unknown" @@ -401,7 +207,7 @@ msgstr "" #: src/Admin/AdminController.php:531 src/Admin/AdminController.php:549 #: src/Admin/AdminController.php:577 src/Admin/AdminController.php:621 #: src/Admin/AdminController.php:811 src/Admin/SettingsController.php:469 -#: src/Frontend/AccountController.php:439 +#: src/Frontend/AccountController.php:442 msgid "Security check failed." msgstr "" @@ -462,7 +268,7 @@ msgstr "" msgid "Export to CSV" msgstr "" -#: src/Admin/AdminController.php:968 wc-licensed-product.php:137 +#: src/Admin/AdminController.php:968 msgid "Settings" msgstr "" @@ -627,6 +433,18 @@ msgstr "" msgid "Bulk Actions" msgstr "" +#: src/Admin/AdminController.php:1273 src/Admin/AdminController.php:1458 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 +msgid "Activate" +msgstr "" + +#: src/Admin/AdminController.php:1274 src/Admin/AdminController.php:1459 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 +msgid "Deactivate" +msgstr "" + #: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419 #: src/Admin/AdminController.php:1460 msgid "Revoke" @@ -644,6 +462,12 @@ msgstr "" msgid "Extend 1 year" msgstr "" +#: src/Admin/AdminController.php:1279 src/Admin/AdminController.php:1428 +#: src/Admin/AdminController.php:1464 src/Admin/VersionAdminController.php:191 +#: src/Admin/VersionAdminController.php:422 +msgid "Delete" +msgstr "" + #: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466 msgid "Apply" msgstr "" @@ -674,6 +498,12 @@ msgstr "" msgid "Domain" msgstr "" +#: src/Admin/AdminController.php:1295 src/Admin/AdminController.php:1446 +#: src/Admin/OrderLicenseController.php:206 +#: src/Admin/VersionAdminController.php:140 +msgid "Status" +msgstr "" + #: src/Admin/AdminController.php:1296 src/Admin/AdminController.php:1447 msgid "Created" msgstr "" @@ -685,11 +515,17 @@ msgstr "" msgid "Expires" msgstr "" +#: src/Admin/AdminController.php:1298 src/Admin/AdminController.php:1449 +#: src/Admin/OrderLicenseController.php:208 +#: src/Admin/VersionAdminController.php:142 +msgid "Actions" +msgstr "" + #: src/Admin/AdminController.php:1304 msgid "No licenses found." msgstr "" -#: src/Admin/AdminController.php:1314 src/Frontend/AccountController.php:260 +#: src/Admin/AdminController.php:1314 src/Frontend/AccountController.php:263 msgid "Copy to clipboard" msgstr "" @@ -709,7 +545,7 @@ msgstr "" msgid "Test" msgstr "" -#: src/Admin/AdminController.php:1400 src/Frontend/AccountController.php:267 +#: src/Admin/AdminController.php:1400 src/Frontend/AccountController.php:270 msgid "Transfer to new domain" msgstr "" @@ -737,27 +573,27 @@ msgstr "" msgid "Testing license..." msgstr "" -#: src/Admin/AdminController.php:1508 src/Frontend/AccountController.php:362 +#: src/Admin/AdminController.php:1508 src/Frontend/AccountController.php:365 msgid "Close" msgstr "" -#: src/Admin/AdminController.php:1517 src/Frontend/AccountController.php:363 +#: src/Admin/AdminController.php:1517 src/Frontend/AccountController.php:366 msgid "Transfer License to New Domain" msgstr "" -#: src/Admin/AdminController.php:1524 src/Frontend/AccountController.php:368 +#: src/Admin/AdminController.php:1524 src/Frontend/AccountController.php:371 msgid "Current Domain" msgstr "" -#: src/Admin/AdminController.php:1528 src/Frontend/AccountController.php:373 +#: src/Admin/AdminController.php:1528 src/Frontend/AccountController.php:376 msgid "New Domain" msgstr "" -#: src/Admin/AdminController.php:1531 src/Frontend/AccountController.php:377 +#: src/Admin/AdminController.php:1531 src/Frontend/AccountController.php:380 msgid "Enter the new domain without http:// or www." msgstr "" -#: src/Admin/AdminController.php:1536 src/Frontend/AccountController.php:382 +#: src/Admin/AdminController.php:1536 src/Frontend/AccountController.php:385 msgid "Transfer License" msgstr "" @@ -765,6 +601,11 @@ msgstr "" msgid "License is VALID" msgstr "" +#: src/Admin/AdminController.php:1609 src/Admin/VersionAdminController.php:81 +#: src/Admin/VersionAdminController.php:136 +msgid "Version" +msgstr "" + #: src/Admin/AdminController.php:1617 msgid "License is INVALID" msgstr "" @@ -942,11 +783,11 @@ msgstr "" #: src/Admin/OrderLicenseController.php:119 #: src/Checkout/CheckoutController.php:436 #: src/Checkout/CheckoutController.php:486 -#: src/Checkout/CheckoutController.php:496 src/License/LicenseManager.php:806 -#: src/Product/VersionManager.php:349 src/Product/VersionManager.php:361 -#: src/Frontend/AccountController.php:146 +#: src/Checkout/CheckoutController.php:496 #: src/Email/LicenseExpirationEmail.php:107 -#: src/Email/LicenseExpiredEmail.php:99 +#: src/Email/LicenseExpiredEmail.php:99 src/Frontend/AccountController.php:148 +#: src/License/LicenseManager.php:806 src/Product/VersionManager.php:349 +#: src/Product/VersionManager.php:361 msgid "Unknown Product" msgstr "" @@ -1020,8 +861,8 @@ msgstr "" #: src/Admin/OrderLicenseController.php:373 #: src/Checkout/CheckoutBlocksIntegration.php:126 -#: src/Frontend/AccountController.php:427 -#: src/Frontend/AccountController.php:459 +#: src/Frontend/AccountController.php:430 +#: src/Frontend/AccountController.php:462 msgid "Please enter a valid domain." msgstr "" @@ -1044,8 +885,8 @@ msgid "Order domain updated." msgstr "" #: src/Admin/OrderLicenseController.php:449 +#: src/Frontend/AccountController.php:468 #: src/Frontend/DownloadController.php:117 -#: src/Frontend/AccountController.php:465 msgid "License not found." msgstr "" @@ -1236,6 +1077,168 @@ msgstr "" msgid "License validation failed." msgstr "" +#: src/Admin/VersionAdminController.php:58 +msgid "Product Versions" +msgstr "" + +#: src/Admin/VersionAdminController.php:78 +msgid "Add New Version" +msgstr "" + +#: src/Admin/VersionAdminController.php:84 +msgid "Use semantic versioning (e.g., 1.0.0)" +msgstr "" + +#: src/Admin/VersionAdminController.php:88 +#: src/Admin/VersionAdminController.php:137 +msgid "Download File" +msgstr "" + +#: src/Admin/VersionAdminController.php:93 +msgid "Select File" +msgstr "" + +#: src/Admin/VersionAdminController.php:96 +#: src/Admin/VersionAdminController.php:110 +msgid "Remove" +msgstr "" + +#: src/Admin/VersionAdminController.php:98 +msgid "" +"Upload or select a file from the media library. Version will be auto-" +"detected from filename (e.g., plugin-v1.2.3.zip)." +msgstr "" + +#: src/Admin/VersionAdminController.php:102 +msgid "Checksum File" +msgstr "" + +#: src/Admin/VersionAdminController.php:107 +msgid "Select Checksum File" +msgstr "" + +#: src/Admin/VersionAdminController.php:112 +msgid "" +"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity." +msgstr "" + +#: src/Admin/VersionAdminController.php:116 +#: src/Admin/VersionAdminController.php:139 +msgid "Release Notes" +msgstr "" + +#: src/Admin/VersionAdminController.php:124 +msgid "Add Version" +msgstr "" + +#: src/Admin/VersionAdminController.php:132 +msgid "Existing Versions" +msgstr "" + +#: src/Admin/VersionAdminController.php:138 +msgid "SHA256" +msgstr "" + +#: src/Admin/VersionAdminController.php:141 +msgid "Released" +msgstr "" + +#: src/Admin/VersionAdminController.php:148 +msgid "No versions found. Add your first version above." +msgstr "" + +#: src/Admin/VersionAdminController.php:165 +#: src/Admin/VersionAdminController.php:396 +msgid "Uploaded file" +msgstr "" + +#: src/Admin/VersionAdminController.php:169 +#: src/Admin/VersionAdminController.php:400 +msgid "No download file" +msgstr "" + +#: src/Admin/VersionAdminController.php:232 +msgid "Are you sure you want to delete this version?" +msgstr "" + +#: src/Admin/VersionAdminController.php:233 +msgid "Please enter a version number." +msgstr "" + +#: src/Admin/VersionAdminController.php:234 +msgid "Please enter a valid version number (e.g., 1.0.0)." +msgstr "" + +#: src/Admin/VersionAdminController.php:235 +msgid "An error occurred. Please try again." +msgstr "" + +#: src/Admin/VersionAdminController.php:236 +msgid "Select Download File" +msgstr "" + +#: src/Admin/VersionAdminController.php:237 +msgid "Use this file" +msgstr "" + +#: src/Admin/VersionAdminController.php:238 +msgid "" +"Invalid checksum file format. File must contain a 64-character SHA256 hash." +msgstr "" + +#: src/Admin/VersionAdminController.php:239 +msgid "Failed to read checksum file." +msgstr "" + +#: src/Admin/VersionAdminController.php:269 +msgid "Product ID and version are required." +msgstr "" + +#: src/Admin/VersionAdminController.php:274 +msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)." +msgstr "" + +#: src/Admin/VersionAdminController.php:279 +msgid "This version already exists." +msgstr "" + +#: src/Admin/VersionAdminController.php:285 +msgid "Product not found." +msgstr "" + +#: src/Admin/VersionAdminController.php:289 +msgid "This product is not a licensed product." +msgstr "" + +#: src/Admin/VersionAdminController.php:306 +msgid "Failed to create version." +msgstr "" + +#: src/Admin/VersionAdminController.php:314 +msgid "Version added successfully." +msgstr "" + +#: src/Admin/VersionAdminController.php:334 +#: src/Admin/VersionAdminController.php:361 +msgid "Version ID is required." +msgstr "" + +#: src/Admin/VersionAdminController.php:340 +msgid "Failed to delete version." +msgstr "" + +#: src/Admin/VersionAdminController.php:343 +msgid "Version deleted successfully." +msgstr "" + +#: src/Admin/VersionAdminController.php:367 +msgid "Failed to update version." +msgstr "" + +#: src/Admin/VersionAdminController.php:371 +msgid "Version updated successfully." +msgstr "" + #: src/Api/RestApiController.php:84 msgid "Too many requests. Please try again later." msgstr "" @@ -1351,226 +1354,54 @@ msgstr "" msgid "Domain for license activation" msgstr "" -#: src/License/PluginLicenseChecker.php:132 -msgid "License settings not configured." +#: src/Email/LicenseEmailController.php:212 +#: src/Email/LicenseEmailController.php:220 +msgid "License Keys:" msgstr "" -#: src/License/PluginLicenseChecker.php:168 -msgid "Could not connect to license server." +#: src/Email/LicenseEmailController.php:268 +msgid "Your License Keys" msgstr "" -#: src/License/LicenseManager.php:412 -msgid "This license has been revoked." -msgstr "" - -#: src/License/LicenseManager.php:422 -msgid "This license has expired." -msgstr "" - -#: src/License/LicenseManager.php:430 -msgid "This license is inactive." -msgstr "" - -#: src/License/LicenseManager.php:440 -msgid "This license is not valid for this domain." -msgstr "" - -#: src/Product/LicensedProductType.php:61 -msgid "Licensed Product" -msgstr "" - -#: src/Product/LicensedProductType.php:82 -msgid "License Settings" -msgstr "" - -#: src/Product/LicensedProductType.php:109 +#: src/Email/LicenseEmailController.php:277 #, php-format -msgid "%d days" +msgid "%d license" +msgid_plural "%d licenses" +msgstr[0] "" +msgstr[1] "" + +#: src/Email/LicenseEmailController.php:308 +#: src/Email/LicenseEmailController.php:352 +msgid "Never" msgstr "" -#: src/Product/LicensedProductType.php:119 -#, php-format -msgid "Leave fields empty to use default settings from %s." +#: src/Email/LicenseEmailController.php:319 +#: src/Email/LicenseEmailController.php:357 +msgid "You can also view your licenses in your account under \"Licenses\"." msgstr "" -#: src/Product/LicensedProductType.php:121 -msgid "WooCommerce > Settings > Licensed Products" +#: src/Email/LicenseEmailController.php:332 +msgid "YOUR LICENSE KEYS" msgstr "" -#: src/Product/LicensedProductType.php:128 -msgid "Max Activations" +#: src/Email/LicenseEmailController.php:343 +#: src/Email/LicenseExpirationEmail.php:207 +#: src/Email/LicenseExpirationEmail.php:270 +#: src/Email/LicenseExpiredEmail.php:191 src/Email/LicenseExpiredEmail.php:256 +msgid "License Key:" msgstr "" -#: src/Product/LicensedProductType.php:131 -#, php-format -msgid "Maximum number of domain activations per license. Default: %d" +#: src/Email/LicenseEmailController.php:345 +#: src/Email/LicenseExpirationEmail.php:215 +#: src/Email/LicenseExpirationEmail.php:271 +#: src/Email/LicenseExpiredEmail.php:199 src/Email/LicenseExpiredEmail.php:257 +msgid "Domain:" msgstr "" -#: src/Product/LicensedProductType.php:146 -msgid "License Validity (Days)" -msgstr "" - -#: src/Product/LicensedProductType.php:149 -#, php-format -msgid "Number of days the license is valid. Leave empty for default (%s)." -msgstr "" - -#: src/Product/LicensedProductType.php:164 -msgid "Bind to Major Version" -msgstr "" - -#: src/Product/LicensedProductType.php:167 -#, php-format -msgid "" -"If enabled, licenses are bound to the major version at purchase time. " -"Default: %s" -msgstr "" - -#: src/Product/LicensedProductType.php:168 -msgid "Yes" -msgstr "" - -#: src/Product/LicensedProductType.php:168 -msgid "No" -msgstr "" - -#: src/Product/LicensedProductType.php:288 -msgid "Version:" -msgstr "" - -#: src/Product/VersionManager.php:166 -msgid "Attachment file not found." -msgstr "" - -#: src/Product/VersionManager.php:177 -#, php-format -msgid "File checksum does not match. Expected: %1$s, Got: %2$s" -msgstr "" - -#: src/Frontend/DownloadController.php:77 -#: src/Frontend/DownloadController.php:101 -msgid "Invalid download link." -msgstr "" - -#: src/Frontend/DownloadController.php:78 -#: src/Frontend/DownloadController.php:88 -#: src/Frontend/DownloadController.php:102 -#: src/Frontend/DownloadController.php:118 -#: src/Frontend/DownloadController.php:128 -#: src/Frontend/DownloadController.php:137 -#: src/Frontend/DownloadController.php:147 -#: src/Frontend/DownloadController.php:156 -#: src/Frontend/DownloadController.php:165 -#: src/Frontend/DownloadController.php:187 -#: src/Frontend/DownloadController.php:203 -msgid "Download Error" -msgstr "" - -#: src/Frontend/DownloadController.php:87 -msgid "Invalid download link format." -msgstr "" - -#: src/Frontend/DownloadController.php:127 -msgid "You do not have permission to download this file." -msgstr "" - -#: src/Frontend/DownloadController.php:136 -msgid "Your license is not active. Please contact support." -msgstr "" - -#: src/Frontend/DownloadController.php:146 -msgid "Version not found." -msgstr "" - -#: src/Frontend/DownloadController.php:155 -msgid "Version does not match your licensed product." -msgstr "" - -#: src/Frontend/DownloadController.php:164 -msgid "This version is no longer available for download." -msgstr "" - -#: src/Frontend/DownloadController.php:186 -msgid "No download file available for this version." -msgstr "" - -#: src/Frontend/DownloadController.php:202 -msgid "Download file not found." -msgstr "" - -#: src/Frontend/AccountController.php:104 -msgid "Please log in to view your licenses." -msgstr "" - -#: src/Frontend/AccountController.php:220 -msgid "You have no licenses yet." -msgstr "" - -#: src/Frontend/AccountController.php:242 -#, php-format -msgid "Order #%s" -msgstr "" - -#: src/Frontend/AccountController.php:293 -msgid "Available Downloads" -msgstr "" - -#: src/Frontend/AccountController.php:302 -#: src/Frontend/AccountController.php:335 -#, php-format -msgid "Version %s" -msgstr "" - -#: src/Frontend/AccountController.php:304 -msgid "Latest" -msgstr "" - -#: src/Frontend/AccountController.php:324 -#, php-format -msgid "Older versions (%d)" -msgstr "" - -#: src/Frontend/AccountController.php:424 -#: src/Frontend/AccountController.php:491 -msgid "License transferred successfully!" -msgstr "" - -#: src/Frontend/AccountController.php:425 -msgid "Transfer failed. Please try again." -msgstr "" - -#: src/Frontend/AccountController.php:426 -msgid "" -"Are you sure you want to transfer this license to a new domain? This action " -"cannot be undone." -msgstr "" - -#: src/Frontend/AccountController.php:445 -msgid "Please log in to transfer a license." -msgstr "" - -#: src/Frontend/AccountController.php:451 -msgid "Invalid license." -msgstr "" - -#: src/Frontend/AccountController.php:469 -msgid "You do not have permission to transfer this license." -msgstr "" - -#: src/Frontend/AccountController.php:474 -msgid "Revoked licenses cannot be transferred." -msgstr "" - -#: src/Frontend/AccountController.php:478 -msgid "Expired licenses cannot be transferred." -msgstr "" - -#: src/Frontend/AccountController.php:483 -msgid "The new domain is the same as the current domain." -msgstr "" - -#: src/Frontend/AccountController.php:495 -msgid "Failed to transfer license. Please try again." +#: src/Email/LicenseEmailController.php:347 +#: src/Email/LicenseExpirationEmail.php:219 +#: src/Email/LicenseExpirationEmail.php:272 +msgid "Expires:" msgstr "" #: src/Email/LicenseExpirationEmail.php:55 @@ -1623,26 +1454,6 @@ msgstr "" msgid "Product:" msgstr "" -#: src/Email/LicenseExpirationEmail.php:207 -#: src/Email/LicenseExpirationEmail.php:270 -#: src/Email/LicenseExpiredEmail.php:191 src/Email/LicenseExpiredEmail.php:256 -#: src/Email/LicenseEmailController.php:343 -msgid "License Key:" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:215 -#: src/Email/LicenseExpirationEmail.php:271 -#: src/Email/LicenseExpiredEmail.php:199 src/Email/LicenseExpiredEmail.php:257 -#: src/Email/LicenseEmailController.php:345 -msgid "Domain:" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:219 -#: src/Email/LicenseExpirationEmail.php:272 -#: src/Email/LicenseEmailController.php:347 -msgid "Expires:" -msgstr "" - #: src/Email/LicenseExpirationEmail.php:235 #: src/Email/LicenseExpirationEmail.php:281 #: src/Email/LicenseExpiredEmail.php:227 src/Email/LicenseExpiredEmail.php:268 @@ -1742,34 +1553,154 @@ msgstr "" msgid "To continue using this product, please renew your license." msgstr "" -#: src/Email/LicenseEmailController.php:212 -#: src/Email/LicenseEmailController.php:220 -msgid "License Keys:" +#: src/Frontend/AccountController.php:105 +msgid "Please log in to view your licenses." msgstr "" -#: src/Email/LicenseEmailController.php:268 -msgid "Your License Keys" +#: src/Frontend/AccountController.php:223 +msgid "You have no licenses yet." msgstr "" -#: src/Email/LicenseEmailController.php:277 +#: src/Frontend/AccountController.php:245 #, php-format -msgid "%d license" -msgid_plural "%d licenses" -msgstr[0] "" -msgstr[1] "" - -#: src/Email/LicenseEmailController.php:308 -#: src/Email/LicenseEmailController.php:352 -msgid "Never" +msgid "Order #%s" msgstr "" -#: src/Email/LicenseEmailController.php:319 -#: src/Email/LicenseEmailController.php:357 -msgid "You can also view your licenses in your account under \"Licenses\"." +#: src/Frontend/AccountController.php:296 +msgid "Available Downloads" msgstr "" -#: src/Email/LicenseEmailController.php:332 -msgid "YOUR LICENSE KEYS" +#: src/Frontend/AccountController.php:305 +#: src/Frontend/AccountController.php:338 +#, php-format +msgid "Version %s" +msgstr "" + +#: src/Frontend/AccountController.php:307 +msgid "Latest" +msgstr "" + +#: src/Frontend/AccountController.php:327 +#, php-format +msgid "Older versions (%d)" +msgstr "" + +#: src/Frontend/AccountController.php:427 +#: src/Frontend/AccountController.php:494 +msgid "License transferred successfully!" +msgstr "" + +#: src/Frontend/AccountController.php:428 +msgid "Transfer failed. Please try again." +msgstr "" + +#: src/Frontend/AccountController.php:429 +msgid "" +"Are you sure you want to transfer this license to a new domain? This action " +"cannot be undone." +msgstr "" + +#: src/Frontend/AccountController.php:448 +msgid "Please log in to transfer a license." +msgstr "" + +#: src/Frontend/AccountController.php:454 +msgid "Invalid license." +msgstr "" + +#: src/Frontend/AccountController.php:472 +msgid "You do not have permission to transfer this license." +msgstr "" + +#: src/Frontend/AccountController.php:477 +msgid "Revoked licenses cannot be transferred." +msgstr "" + +#: src/Frontend/AccountController.php:481 +msgid "Expired licenses cannot be transferred." +msgstr "" + +#: src/Frontend/AccountController.php:486 +msgid "The new domain is the same as the current domain." +msgstr "" + +#: src/Frontend/AccountController.php:498 +msgid "Failed to transfer license. Please try again." +msgstr "" + +#: src/Frontend/DownloadController.php:77 +#: src/Frontend/DownloadController.php:101 +msgid "Invalid download link." +msgstr "" + +#: src/Frontend/DownloadController.php:78 +#: src/Frontend/DownloadController.php:88 +#: src/Frontend/DownloadController.php:102 +#: src/Frontend/DownloadController.php:118 +#: src/Frontend/DownloadController.php:128 +#: src/Frontend/DownloadController.php:137 +#: src/Frontend/DownloadController.php:147 +#: src/Frontend/DownloadController.php:156 +#: src/Frontend/DownloadController.php:165 +#: src/Frontend/DownloadController.php:187 +#: src/Frontend/DownloadController.php:203 +msgid "Download Error" +msgstr "" + +#: src/Frontend/DownloadController.php:87 +msgid "Invalid download link format." +msgstr "" + +#: src/Frontend/DownloadController.php:127 +msgid "You do not have permission to download this file." +msgstr "" + +#: src/Frontend/DownloadController.php:136 +msgid "Your license is not active. Please contact support." +msgstr "" + +#: src/Frontend/DownloadController.php:146 +msgid "Version not found." +msgstr "" + +#: src/Frontend/DownloadController.php:155 +msgid "Version does not match your licensed product." +msgstr "" + +#: src/Frontend/DownloadController.php:164 +msgid "This version is no longer available for download." +msgstr "" + +#: src/Frontend/DownloadController.php:186 +msgid "No download file available for this version." +msgstr "" + +#: src/Frontend/DownloadController.php:202 +msgid "Download file not found." +msgstr "" + +#: src/License/LicenseManager.php:412 +msgid "This license has been revoked." +msgstr "" + +#: src/License/LicenseManager.php:422 +msgid "This license has expired." +msgstr "" + +#: src/License/LicenseManager.php:430 +msgid "This license is inactive." +msgstr "" + +#: src/License/LicenseManager.php:440 +msgid "This license is not valid for this domain." +msgstr "" + +#: src/License/PluginLicenseChecker.php:132 +msgid "License settings not configured." +msgstr "" + +#: src/License/PluginLicenseChecker.php:168 +msgid "Could not connect to license server." msgstr "" #: src/Plugin.php:318 @@ -1785,11 +1716,82 @@ msgstr "" msgid "Configure License" msgstr "" -#: wc-licensed-product.php:61 -#, php-format -msgid "%s requires WooCommerce to be installed and active." +#: src/Product/LicensedProductType.php:61 +msgid "Licensed Product" msgstr "" -#: wc-licensed-product.php:119 -msgid "WC Licensed Product requires WooCommerce to be installed and active." +#: src/Product/LicensedProductType.php:82 +msgid "License Settings" +msgstr "" + +#: src/Product/LicensedProductType.php:109 +#, php-format +msgid "%d days" +msgstr "" + +#: src/Product/LicensedProductType.php:119 +#, php-format +msgid "Leave fields empty to use default settings from %s." +msgstr "" + +#: src/Product/LicensedProductType.php:121 +msgid "WooCommerce > Settings > Licensed Products" +msgstr "" + +#: src/Product/LicensedProductType.php:128 +msgid "Max Activations" +msgstr "" + +#: src/Product/LicensedProductType.php:131 +#, php-format +msgid "Maximum number of domain activations per license. Default: %d" +msgstr "" + +#: src/Product/LicensedProductType.php:146 +msgid "License Validity (Days)" +msgstr "" + +#: src/Product/LicensedProductType.php:149 +#, php-format +msgid "Number of days the license is valid. Leave empty for default (%s)." +msgstr "" + +#: src/Product/LicensedProductType.php:164 +msgid "Bind to Major Version" +msgstr "" + +#: src/Product/LicensedProductType.php:167 +#, php-format +msgid "" +"If enabled, licenses are bound to the major version at purchase time. " +"Default: %s" +msgstr "" + +#: src/Product/LicensedProductType.php:168 +msgid "Yes" +msgstr "" + +#: src/Product/LicensedProductType.php:168 +msgid "No" +msgstr "" + +#: src/Product/LicensedProductType.php:288 +msgid "Version:" +msgstr "" + +#: src/Product/VersionManager.php:166 +msgid "Attachment file not found." +msgstr "" + +#: src/Product/VersionManager.php:177 +#, php-format +msgid "File checksum does not match. Expected: %1$s, Got: %2$s" +msgstr "" + +#: templates/frontend/licenses.html.twig:72 +msgid "API Verification Secret" +msgstr "" + +#: templates/frontend/licenses.html.twig:77 +msgid "Use this secret to verify signed API responses. Keep it secure." msgstr "" diff --git a/src/Api/ResponseSigner.php b/src/Api/ResponseSigner.php index 0d81ece..540066c 100644 --- a/src/Api/ResponseSigner.php +++ b/src/Api/ResponseSigner.php @@ -147,9 +147,52 @@ final class ResponseSigner */ private function deriveKey(string $licenseKey): string { - // HKDF-like key derivation - $prk = hash_hmac('sha256', $licenseKey, $this->serverSecret, true); + return self::deriveCustomerSecret($licenseKey, $this->serverSecret); + } - return hash_hmac('sha256', $prk . "\x01", $this->serverSecret); + /** + * Derive a customer-specific secret from a license key + * + * This secret is unique per license and can be shared with the customer + * to verify signed API responses. Each customer gets their own secret + * derived from their license key. + * + * @param string $licenseKey The customer's license key + * @param string $serverSecret The server's master secret + * @return string The derived secret (64 hex characters) + */ + public static function deriveCustomerSecret(string $licenseKey, string $serverSecret): string + { + // HKDF-like key derivation + $prk = hash_hmac('sha256', $licenseKey, $serverSecret, true); + + return hash_hmac('sha256', $prk . "\x01", $serverSecret); + } + + /** + * Get the customer secret for a license key using the configured server secret + * + * @param string $licenseKey The customer's license key + * @return string|null The derived secret, or null if server secret is not configured + */ + public static function getCustomerSecretForLicense(string $licenseKey): ?string + { + $serverSecret = defined('WC_LICENSE_SERVER_SECRET') ? WC_LICENSE_SERVER_SECRET : ''; + + if (empty($serverSecret)) { + return null; + } + + return self::deriveCustomerSecret($licenseKey, $serverSecret); + } + + /** + * Check if response signing is enabled + * + * @return bool True if server secret is configured + */ + public static function isSigningEnabled(): bool + { + return defined('WC_LICENSE_SERVER_SECRET') && !empty(WC_LICENSE_SERVER_SECRET); } } diff --git a/src/Frontend/AccountController.php b/src/Frontend/AccountController.php index 6b26039..85b165b 100644 --- a/src/Frontend/AccountController.php +++ b/src/Frontend/AccountController.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace Jeremias\WcLicensedProduct\Frontend; +use Jeremias\WcLicensedProduct\Api\ResponseSigner; use Jeremias\WcLicensedProduct\License\LicenseManager; use Jeremias\WcLicensedProduct\Product\VersionManager; use Twig\Environment; @@ -114,6 +115,7 @@ final class AccountController echo $this->twig->render('frontend/licenses.html.twig', [ 'packages' => $packages, 'has_packages' => !empty($packages), + 'signing_enabled' => ResponseSigner::isSigningEnabled(), ]); } catch (\Exception $e) { // Fallback to PHP template if Twig fails @@ -161,6 +163,7 @@ final class AccountController 'status' => $license->getStatus(), 'expires_at' => $license->getExpiresAt(), 'is_transferable' => in_array($license->getStatus(), ['active', 'inactive'], true), + 'customer_secret' => ResponseSigner::getCustomerSecretForLicense($license->getLicenseKey()), ]; // Track if package has at least one active license diff --git a/templates/frontend/licenses.html.twig b/templates/frontend/licenses.html.twig index 71d1a69..f0a3f67 100644 --- a/templates/frontend/licenses.html.twig +++ b/templates/frontend/licenses.html.twig @@ -65,6 +65,26 @@ {% endif %} + {% if signing_enabled and license.customer_secret %} +

+ + +
+ {% endif %} {% endfor %}