diff --git a/src/components/LicenseStatus.vue b/src/components/LicenseStatus.vue
index 43c453e..f3975cb 100644
--- a/src/components/LicenseStatus.vue
+++ b/src/components/LicenseStatus.vue
@@ -9,7 +9,11 @@
-
+
@@ -134,9 +138,10 @@ async function refreshLicenseStatus() {
}
function purchaseLicense() {
- alert(
- `请联系管理员或访问官方网站购买许可证。\nDomain: ${licenseInfo.value?.domain}\nPlugin: ${licenseInfo.value?.pluginId}`,
- );
+ const { name, email } = kintone.getLoginUser();
+ const domain = licenseInfo.value?.domain;
+ const pluginId = licenseInfo.value?.pluginId;
+ window.open(`https://alisurvey.alicorns.co.jp/s/Iuc5RxZv?input1761283180784=${domain}&input1761283200616=${pluginId}&input1761283314263=${name}&input1761283275767=${email}`);
}
function hidePaidMsg() {
diff --git a/src/css/license.css b/src/css/license.css
index 1210523..5ef0c5c 100644
--- a/src/css/license.css
+++ b/src/css/license.css
@@ -70,14 +70,19 @@
border-color: #33691E;
}
+.license-status-info .action-btn .open-icon {
+ margin-left: 2px;
+ vertical-align: middle;
+}
+
.notification-link {
color: #fff;
- opacity: 0.8;
text-decoration: underline;
}
.notification-link:hover {
- opacity: 1;
+ color: #fff;
+ opacity: 0.8;
}
.text-red {
diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts
index 6cebda0..6e29c9e 100644
--- a/src/i18n/lang/en.ts
+++ b/src/i18n/lang/en.ts
@@ -54,7 +54,8 @@ export default {
},
error: {
fetchFailed: 'Remote license check failed: {e}',
- checkFailed: 'License check failed, plugin disabled: {e}'
+ checkFailed: 'License check failed, plugin disabled: {e}',
+ jwtFailed: 'JWT verification or parsing failed: {e}',
}
},
};
diff --git a/src/i18n/lang/ja.ts b/src/i18n/lang/ja.ts
index 1c39c66..778be74 100644
--- a/src/i18n/lang/ja.ts
+++ b/src/i18n/lang/ja.ts
@@ -42,7 +42,7 @@ export default {
},
notification: {
days: '今日 | 明日 | {count}日後',
- gotoLink: 'ご利用には「プラグインの設定」をご確認ください。',
+ gotoLink: 'ご利用には「プラグインの設定」をご確認ください。',
expired: 'プラグイン「{plugin}」の有効期限が切れました。',
warning: 'プラグイン「{plugin}」の試用期間が{days}で終了します。'
},
@@ -57,7 +57,8 @@ export default {
},
error: {
fetchFailed: 'リモートライセンスチェックに失敗しました: {e}',
- checkFailed: 'ライセンスチェックに失敗しました。プラグイン機能が無効になりました: {e}'
+ checkFailed: 'ライセンスチェックに失敗しました。プラグイン機能が無効になりました: {e}',
+ jwtFailed: 'JWTの検証または解析に失敗しました: {e}',
}
},
};
diff --git a/src/services/license-service.ts b/src/services/license-service.ts
index 3fdef8c..0d83371 100644
--- a/src/services/license-service.ts
+++ b/src/services/license-service.ts
@@ -51,11 +51,11 @@ export class LicenseService {
// 验证完整的JWT
const result = KJUR.jws.JWS.verifyJWT(savedLicense.jwt, rsaPublicKey.trim(), {alg: ['RS256']});
if (!result) {
- console.warn('JWT signature verification failed');
+ console.warn($t('license.error.jwtFailed', { e : '' }));
return false;
}
} catch (error) {
- console.error('JWT verification or parsing failed:', error);
+ console.warn($t('license.error.jwtFailed', { e : error }));
return false;
}
diff --git a/src/utils/license-storage.ts b/src/utils/license-storage.ts
index e9986eb..edd3867 100644
--- a/src/utils/license-storage.ts
+++ b/src/utils/license-storage.ts
@@ -1,24 +1,12 @@
// 本地存储加密工具类
import { LicenseService } from '@/services/license-service';
-import type { LicenseInfo, LicenseJWSResult, LicenseSetting, SavedLicense } from '@/types/license';
+import type { LicenseJWSResult, LicenseSetting, SavedLicense } from '@/types/license';
import { KJUR } from 'jsrsasign';
export class LicenseStorage {
private static readonly STORAGE_KEY_PREFIX = 'alicorns_plugin_';
private static readonly STORAGE_SETTING_KEY_PREFIX = this.STORAGE_KEY_PREFIX + 'setting_';
- /**
- * 解码JWT(不验证)
- */
- private static parseJWT(jwt: string) {
- try {
- return KJUR.jws.JWS.parse(jwt);
- } catch (error) {
- console.error('JWT parsing failed:', error);
- return null;
- }
- }
-
/**
* 生成存储key
*/
@@ -89,7 +77,7 @@ export class LicenseStorage {
// decode
let decodedJWT: LicenseJWSResult;
try {
- decodedJWT = this.parseJWT(storedJWT) as LicenseJWSResult;
+ decodedJWT = KJUR.jws.JWS.parse(storedJWT) as LicenseJWSResult;
if (!decodedJWT) {
return null;
}