smart-admin-web 10.14.0 → 10.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +5 -5
  2. package/dist/api/index.d.ts +37 -0
  3. package/dist/api/index.js +35 -14
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/schema.d.ts +381 -3
  6. package/dist/assets/icons/ph-subset.json.js +3 -3
  7. package/dist/assets/smart-logo.svg.js +5 -0
  8. package/dist/assets/smart-logo.svg.js.map +1 -0
  9. package/dist/components/SmartLogo.vue.d.ts +3 -0
  10. package/dist/components/SmartLogo.vue.js +1 -1
  11. package/dist/components/SmartLogo2.vue.js +22 -64
  12. package/dist/components/SmartLogo2.vue.js.map +1 -1
  13. package/dist/composables/useLoginHero.d.ts +2 -0
  14. package/dist/composables/useLoginHero.js +22 -0
  15. package/dist/composables/useLoginHero.js.map +1 -0
  16. package/dist/composables/usePageTitle.js +16 -14
  17. package/dist/composables/usePageTitle.js.map +1 -1
  18. package/dist/composables/useSite.d.ts +5 -0
  19. package/dist/composables/useSite.js +16 -13
  20. package/dist/composables/useSite.js.map +1 -1
  21. package/dist/index.js +92 -91
  22. package/dist/lib/favicon.d.ts +1 -0
  23. package/dist/lib/favicon.js +12 -0
  24. package/dist/lib/favicon.js.map +1 -0
  25. package/dist/lib/loginHero.d.ts +16 -0
  26. package/dist/lib/loginHero.js +33 -0
  27. package/dist/lib/loginHero.js.map +1 -0
  28. package/dist/lib/logoCrop.d.ts +25 -0
  29. package/dist/lib/logoCrop.js +22 -0
  30. package/dist/lib/logoCrop.js.map +1 -0
  31. package/dist/lib/runtime.d.ts +2 -0
  32. package/dist/lib/runtime.js +1 -1
  33. package/dist/lib/runtime.js.map +1 -1
  34. package/dist/lib/securityRules.d.ts +26 -0
  35. package/dist/lib/securityRules.js +86 -0
  36. package/dist/lib/securityRules.js.map +1 -0
  37. package/dist/locales/en-US.d.ts +242 -28
  38. package/dist/locales/en-US.js +262 -58
  39. package/dist/locales/en-US.js.map +1 -1
  40. package/dist/locales/zh-CN.d.ts +242 -28
  41. package/dist/locales/zh-CN.js +257 -58
  42. package/dist/locales/zh-CN.js.map +1 -1
  43. package/dist/router/viewRegistry.js +10 -10
  44. package/dist/router/viewRegistry.js.map +1 -1
  45. package/dist/style.css +1 -1
  46. package/dist/utils/oauthBrand.d.ts +34 -9
  47. package/dist/utils/oauthBrand.js +70 -74
  48. package/dist/utils/oauthBrand.js.map +1 -1
  49. package/dist/views/login/components/LoginHeroPanel.vue.d.ts +18 -0
  50. package/dist/views/login/components/LoginHeroPanel.vue.js +8 -0
  51. package/dist/views/login/components/LoginHeroPanel.vue.js.map +1 -0
  52. package/dist/views/login/components/LoginHeroPanel2.vue.js +66 -0
  53. package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -0
  54. package/dist/views/login/skins/SplitPanel.vue.js +1 -1
  55. package/dist/views/login/skins/SplitPanel2.vue.js +39 -59
  56. package/dist/views/login/skins/SplitPanel2.vue.js.map +1 -1
  57. package/dist/views/system/config/components/AdminMock.vue.js +8 -0
  58. package/dist/views/system/config/components/AdminMock.vue.js.map +1 -0
  59. package/dist/views/system/config/components/AdminMock2.vue.js +76 -0
  60. package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -0
  61. package/dist/views/system/config/components/AdvancedSection.vue.js +5 -0
  62. package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -0
  63. package/dist/views/system/config/components/AdvancedSection2.vue.js +135 -0
  64. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -0
  65. package/dist/views/system/config/components/BrandSection.vue.d.ts +7 -0
  66. package/dist/views/system/config/components/BrandSection.vue.js +8 -0
  67. package/dist/views/system/config/components/BrandSection.vue.js.map +1 -0
  68. package/dist/views/system/config/components/BrandSection2.vue.js +264 -0
  69. package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -0
  70. package/dist/views/system/config/components/CfgGroup.vue.d.ts +18 -0
  71. package/dist/views/system/config/components/CfgGroup.vue.js +8 -0
  72. package/dist/views/system/config/components/CfgGroup.vue.js.map +1 -0
  73. package/dist/views/system/config/components/CfgGroup2.vue.js +22 -0
  74. package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -0
  75. package/dist/views/system/config/components/CfgRow.vue.d.ts +26 -0
  76. package/dist/views/system/config/components/CfgRow.vue.js +9 -0
  77. package/dist/views/system/config/components/CfgRow.vue.js.map +1 -0
  78. package/dist/views/system/config/components/CfgRow2.vue.js +53 -0
  79. package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -0
  80. package/dist/views/system/config/components/CfgSegment.vue.d.ts +28 -0
  81. package/dist/views/system/config/components/CfgSegment.vue.js +8 -0
  82. package/dist/views/system/config/components/CfgSegment.vue.js.map +1 -0
  83. package/dist/views/system/config/components/CfgSegment2.vue.js +44 -0
  84. package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -0
  85. package/dist/views/system/config/components/ConfigFormModal.vue.js +5 -2
  86. package/dist/views/system/config/components/ConfigFormModal.vue.js.map +1 -1
  87. package/dist/views/system/config/components/ConfigFormModal2.vue.js +66 -56
  88. package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
  89. package/dist/views/system/config/components/JobSection.vue.js +8 -0
  90. package/dist/views/system/config/components/JobSection.vue.js.map +1 -0
  91. package/dist/views/system/config/components/JobSection2.vue.js +138 -0
  92. package/dist/views/system/config/components/JobSection2.vue.js.map +1 -0
  93. package/dist/views/system/config/components/{GroupExtraConfig.vue.d.ts → LoginMock.vue.d.ts} +3 -4
  94. package/dist/views/system/config/components/LoginMock.vue.js +8 -0
  95. package/dist/views/system/config/components/LoginMock.vue.js.map +1 -0
  96. package/dist/views/system/config/components/LoginMock2.vue.js +121 -0
  97. package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -0
  98. package/dist/views/system/config/components/LogoCropper.vue.d.ts +10 -0
  99. package/dist/views/system/config/components/LogoCropper.vue.js +8 -0
  100. package/dist/views/system/config/components/LogoCropper.vue.js.map +1 -0
  101. package/dist/views/system/config/components/LogoCropper2.vue.js +122 -0
  102. package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -0
  103. package/dist/views/system/config/components/LogoEditor.vue.js +8 -0
  104. package/dist/views/system/config/components/LogoEditor.vue.js.map +1 -0
  105. package/dist/views/system/config/components/LogoEditor2.vue.js +163 -0
  106. package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -0
  107. package/dist/views/system/config/components/ProviderSheet.vue.d.ts +17 -0
  108. package/dist/views/system/config/components/ProviderSheet.vue.js +8 -0
  109. package/dist/views/system/config/components/ProviderSheet.vue.js.map +1 -0
  110. package/dist/views/system/config/components/ProviderSheet2.vue.js +343 -0
  111. package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -0
  112. package/dist/views/system/config/components/ScaleToFit.vue.d.ts +17 -0
  113. package/dist/views/system/config/components/ScaleToFit.vue.js +8 -0
  114. package/dist/views/system/config/components/ScaleToFit.vue.js.map +1 -0
  115. package/dist/views/system/config/components/ScaleToFit2.vue.js +41 -0
  116. package/dist/views/system/config/components/ScaleToFit2.vue.js.map +1 -0
  117. package/dist/views/system/config/components/SectionLayout.vue.d.ts +28 -0
  118. package/dist/views/system/config/components/SectionLayout.vue.js +8 -0
  119. package/dist/views/system/config/components/SectionLayout.vue.js.map +1 -0
  120. package/dist/views/system/config/components/SectionLayout2.vue.js +45 -0
  121. package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -0
  122. package/dist/views/system/config/components/SecuritySection.vue.js +8 -0
  123. package/dist/views/system/config/components/SecuritySection.vue.js.map +1 -0
  124. package/dist/views/system/config/components/SecuritySection2.vue.js +416 -0
  125. package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -0
  126. package/dist/views/system/config/components/SensitiveSection.vue.js +8 -0
  127. package/dist/views/system/config/components/SensitiveSection.vue.js.map +1 -0
  128. package/dist/views/system/config/components/SensitiveSection2.vue.js +209 -0
  129. package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -0
  130. package/dist/views/system/config/components/SigninSection.vue.js +8 -0
  131. package/dist/views/system/config/components/SigninSection.vue.js.map +1 -0
  132. package/dist/views/system/config/components/SigninSection2.vue.js +201 -0
  133. package/dist/views/system/config/components/SigninSection2.vue.js.map +1 -0
  134. package/dist/views/system/config/components/UploadSection.vue.d.ts +3 -0
  135. package/dist/views/system/config/components/UploadSection.vue.js +8 -0
  136. package/dist/views/system/config/components/UploadSection.vue.js.map +1 -0
  137. package/dist/views/system/config/components/UploadSection2.vue.js +167 -0
  138. package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -0
  139. package/dist/views/system/config/draft.d.ts +148 -0
  140. package/dist/views/system/config/draft.js +170 -0
  141. package/dist/views/system/config/draft.js.map +1 -0
  142. package/dist/views/system/config/flash.d.ts +2 -0
  143. package/dist/views/system/config/flash.js +9 -0
  144. package/dist/views/system/config/flash.js.map +1 -0
  145. package/dist/views/system/config/groups.d.ts +35 -7
  146. package/dist/views/system/config/groups.js +99 -14
  147. package/dist/views/system/config/groups.js.map +1 -1
  148. package/dist/views/system/config/index.vue.js +4 -1
  149. package/dist/views/system/config/index.vue.js.map +1 -1
  150. package/dist/views/system/config/index2.vue.js +180 -115
  151. package/dist/views/system/config/index2.vue.js.map +1 -1
  152. package/dist/views/system/config/providerForm.d.ts +33 -0
  153. package/dist/views/system/config/providerForm.js +63 -0
  154. package/dist/views/system/config/providerForm.js.map +1 -0
  155. package/package.json +4 -4
  156. package/dist/views/system/config/components/ExternalAuthConfig.vue.js +0 -8
  157. package/dist/views/system/config/components/ExternalAuthConfig.vue.js.map +0 -1
  158. package/dist/views/system/config/components/ExternalAuthConfig2.vue.js +0 -218
  159. package/dist/views/system/config/components/ExternalAuthConfig2.vue.js.map +0 -1
  160. package/dist/views/system/config/components/GroupExtraConfig.vue.js +0 -8
  161. package/dist/views/system/config/components/GroupExtraConfig.vue.js.map +0 -1
  162. package/dist/views/system/config/components/GroupExtraConfig2.vue.js +0 -108
  163. package/dist/views/system/config/components/GroupExtraConfig2.vue.js.map +0 -1
  164. package/dist/views/system/config/components/HighSensConfig.vue.js +0 -5
  165. package/dist/views/system/config/components/HighSensConfig.vue.js.map +0 -1
  166. package/dist/views/system/config/components/HighSensConfig2.vue.js +0 -134
  167. package/dist/views/system/config/components/HighSensConfig2.vue.js.map +0 -1
  168. package/dist/views/system/config/components/JobConfig.vue.js +0 -5
  169. package/dist/views/system/config/components/JobConfig.vue.js.map +0 -1
  170. package/dist/views/system/config/components/JobConfig2.vue.js +0 -116
  171. package/dist/views/system/config/components/JobConfig2.vue.js.map +0 -1
  172. package/dist/views/system/config/components/OtherConfig.vue.js +0 -5
  173. package/dist/views/system/config/components/OtherConfig.vue.js.map +0 -1
  174. package/dist/views/system/config/components/OtherConfig2.vue.js +0 -121
  175. package/dist/views/system/config/components/OtherConfig2.vue.js.map +0 -1
  176. package/dist/views/system/config/components/SecurityConfig.vue.js +0 -8
  177. package/dist/views/system/config/components/SecurityConfig.vue.js.map +0 -1
  178. package/dist/views/system/config/components/SecurityConfig2.vue.js +0 -456
  179. package/dist/views/system/config/components/SecurityConfig2.vue.js.map +0 -1
  180. package/dist/views/system/config/components/SysBaseConfig.vue.js +0 -5
  181. package/dist/views/system/config/components/SysBaseConfig.vue.js.map +0 -1
  182. package/dist/views/system/config/components/SysBaseConfig2.vue.js +0 -107
  183. package/dist/views/system/config/components/SysBaseConfig2.vue.js.map +0 -1
  184. package/dist/views/system/config/components/UploadConfig.vue.js +0 -5
  185. package/dist/views/system/config/components/UploadConfig.vue.js.map +0 -1
  186. package/dist/views/system/config/components/UploadConfig2.vue.js +0 -135
  187. package/dist/views/system/config/components/UploadConfig2.vue.js.map +0 -1
  188. /package/dist/views/system/config/components/{ExternalAuthConfig.vue.d.ts → AdminMock.vue.d.ts} +0 -0
  189. /package/dist/views/system/config/components/{HighSensConfig.vue.d.ts → AdvancedSection.vue.d.ts} +0 -0
  190. /package/dist/views/system/config/components/{JobConfig.vue.d.ts → JobSection.vue.d.ts} +0 -0
  191. /package/dist/views/system/config/components/{OtherConfig.vue.d.ts → LogoEditor.vue.d.ts} +0 -0
  192. /package/dist/views/system/config/components/{SecurityConfig.vue.d.ts → SecuritySection.vue.d.ts} +0 -0
  193. /package/dist/views/system/config/components/{SysBaseConfig.vue.d.ts → SensitiveSection.vue.d.ts} +0 -0
  194. /package/dist/views/system/config/components/{UploadConfig.vue.d.ts → SigninSection.vue.d.ts} +0 -0
@@ -528,108 +528,305 @@ const e = {
528
528
  deleteConfirm: 'Delete config "{name}"?',
529
529
  saved: "Saved",
530
530
  deleted: "Deleted",
531
- groupManagedBy: 'This group belongs to the "{tab}" tab; saved configs appear there',
532
- groupExtra: {
533
- title: "Other configs in this group",
534
- hint: "Configs in this group that the form above does not list. View, edit or delete them here."
535
- },
531
+ keyManagedBy: 'This key is managed by the "{tab}" form. Edit it there after saving.',
532
+ unsaved: "{n} unsaved change(s)",
533
+ unsavedTab: "Unsaved changes",
534
+ discard: "Discard",
535
+ leaveTitle: "Discard unsaved changes?",
536
+ leaveConfirm: "You have unsaved configuration changes. They will be lost if you leave.",
536
537
  tab: {
537
- base: "General",
538
+ brand: "Branding & login",
538
539
  security: "Security",
539
- externalAuth: "External login",
540
- upload: "Upload",
540
+ signin: "Sign-in methods",
541
+ sensitive: "Sensitive actions",
542
+ upload: "Uploads",
541
543
  job: "Scheduled jobs",
542
- other: "Other"
544
+ advanced: "Advanced"
545
+ },
546
+ brand: {
547
+ desc: "How the site looks in the browser tab, the sidebar, the footer and the login page.",
548
+ preview: "Live preview",
549
+ previewAdmin: "Admin",
550
+ previewLogin: "Login",
551
+ groupSite: "Site",
552
+ groupLogin: "Login page",
553
+ copyrightPh: "Leave empty to show the site name",
554
+ copyrightUrlHint: "When set, the footer copyright becomes a link"
555
+ },
556
+ logo: {
557
+ title: "Logo",
558
+ edit: "Change logo",
559
+ upload: "Upload a new image…",
560
+ useUrl: "Use an image URL…",
561
+ remove: "Remove, use the default",
562
+ help: "PNG, JPG or WEBP, cropped square; also the browser tab icon",
563
+ fallback: "Without a logo the built-in one is used. The browser tab icon follows the logo too.",
564
+ badType: "Only PNG, JPG and WEBP images are supported",
565
+ tooLarge: "The image must be at most {mb} MB",
566
+ cropTitle: "Crop new logo",
567
+ cropTip: "Drag or use the arrow keys to reposition; scroll, the slider or +/- to zoom",
568
+ zoom: "Zoom",
569
+ apply: "Set new logo",
570
+ cropFailed: "Cropping failed, try another image",
571
+ badUrl: "Enter an address starting with http:// or https://, or a site path starting with /",
572
+ urlHint: "The image must be publicly readable. A square image works best."
573
+ },
574
+ advanced: {
575
+ desc: "Configs that belong to none of the tabs above, edited as raw key/value rows. Keys the tabs above manage are not listed here."
576
+ },
577
+ preview: {
578
+ minutes: "{n} min",
579
+ hours: "{n} h",
580
+ days: "{n} days",
581
+ off: "(not enabled)",
582
+ sep: ", ",
583
+ req: {
584
+ upper: "an uppercase letter",
585
+ lower: "a lowercase letter",
586
+ digit: "a digit",
587
+ special: "a special character"
588
+ },
589
+ lock: "After {count} wrong passwords in a row the account is locked for {minutes} min",
590
+ lockOff: "Wrong passwords never lock the account",
591
+ captcha: "Sign-in asks for a captcha ({type})",
592
+ totp: "Users can use an authenticator as a second factor",
593
+ totpSuper: "Users can use an authenticator as a second factor; super admins must",
594
+ smsMfa: "Users with a bound phone verify an SMS code at sign-in",
595
+ password: "Passwords need at least {min} characters and {reqs}",
596
+ passwordMin: "Passwords need at least {min} characters",
597
+ expire: "Passwords must be changed every {days} days",
598
+ noExpire: "Passwords never expire",
599
+ history: "A new password cannot repeat the last {n}",
600
+ historyOff: "A new password may repeat an old one",
601
+ firstChange: "Admin-created accounts must change their password at first sign-in",
602
+ firstChangeOff: "New accounts keep their initial password at first sign-in",
603
+ session: "Access tokens renew every {access}; sign-in lasts up to {refresh}",
604
+ rateLimit: "At most {permit} requests per {seconds} s from one source"
543
605
  },
544
606
  job: {
545
- logRetentionDays: "Log retention days",
607
+ desc: "How long run logs are kept and who hears about failures.",
608
+ preview: "Live preview · effect",
609
+ groupLog: "Run logs",
610
+ groupAlert: "Failure alerts",
611
+ logRetentionDays: "Keep for",
612
+ logRetentionHint: "Older logs are cleaned up daily",
546
613
  alertEmails: "Alert emails",
547
- alertEmailsHint: "Separate multiple emails with commas"
614
+ alertEmailsHint: "Press Enter to add; none means no email",
615
+ previewRetention: "Run logs are kept for {days} days; older ones are cleaned up daily",
616
+ previewKeep: "Keep {days} days",
617
+ previewAxisStart: "{days} days ago",
618
+ previewToday: "Today",
619
+ previewTo: "To",
620
+ previewSubject: "Subject",
621
+ previewSubjectText: "[{site}] Scheduled job failed: Daily report",
622
+ previewBody: 'Job "Daily report" failed at 02:00 after 3 retries.',
623
+ previewError: "database connection timed out (30s)",
624
+ previewNoAlert: "Failed runs send no email; they are only recorded in the run log"
548
625
  },
549
626
  externalAuth: {
550
- hint: "Choose which deployed third-party sign-in methods appear on the login page. Disabled methods are hidden and authorize is rejected. Secrets stay in server appsettings.",
551
- empty: "No external login providers registered (install optional packages or configure OIDC)",
552
- showOnLogin: "On login page",
553
- hidden: "Hidden",
554
- loginVisible: "Show on login page",
555
- summary: "{total} methods · {on} shown on login",
556
- summaryFull: "{total} total · {registered} configured · {on} on login",
557
- reset: "Reset",
558
- notConfigured: "Not configured",
559
- notConfiguredTip: "Not registered on this deployment (package/secrets missing). Cannot show on login.",
627
+ preview: "Live preview · sign-in box",
628
+ previewOther: "Other sign-in options",
629
+ hint: "Which sign-in options appear on the login page. Connection details for each third party are entered in its Settings and stored encrypted.",
630
+ groupLocal: "Local account",
631
+ groupThird: "Third-party",
632
+ password: "Username and password",
633
+ passwordHint: "Always available",
634
+ smsHint: "Sign in with phone number and SMS code",
635
+ state: {
636
+ notInstalled: "Not installed",
637
+ unconfigured: "Not configured",
638
+ configured: "Configured"
639
+ },
640
+ settings: "Settings",
641
+ addOidc: "Add OIDC",
642
+ needPackage: "Install the {pkg} package on the server first",
643
+ codeRegistered: "Registered in code; not configured here",
560
644
  linkByAccount: "Link by account",
645
+ linkByAccountHint: "People with the same account ID are bound to the local account on first sign-in; asks to confirm",
561
646
  linkByAccountConfirmTitle: "Turn on link by account?",
562
- linkByAccountConfirm: "The first time someone signs in with {name}, if their {name} account ID is exactly the same as a local account, the two are bound and they are signed in directly. Super admins, disabled accounts and accounts already bound to {name} are never linked. Make sure both sides are the same people first, e.g. local accounts were synced from {name}."
647
+ linkByAccountConfirm: "The first time someone signs in with {name}, if their {name} account ID is exactly the same as a local account, the two are bound and they are signed in directly. Super admins, disabled accounts and accounts already bound to {name} are never linked. Make sure both sides are the same people first, e.g. local accounts were synced from {name}.",
648
+ field: {
649
+ displayName: "Display name",
650
+ code: "Identifier",
651
+ corpId: "Corp ID",
652
+ agentId: "Agent ID",
653
+ corpSecret: "App secret",
654
+ appKey: "AppKey",
655
+ appSecret: "AppSecret",
656
+ clientId: "Client ID",
657
+ clientSecret: "Client secret",
658
+ appId: "AppId",
659
+ authority: "Authority",
660
+ scopes: "Scopes",
661
+ usePkce: "Use PKCE"
662
+ },
663
+ sheet: {
664
+ title: "{name} sign-in settings",
665
+ addOidc: "Add OIDC",
666
+ oidcHint: "A standard OpenID Connect identity source",
667
+ secretNote: "Secrets are stored encrypted and are not displayed after saving",
668
+ namePlaceholder: "e.g. Company SSO",
669
+ codePlaceholder: "lowercase letters, digits, hyphens",
670
+ codeFixed: "Cannot be changed after saving",
671
+ codeTaken: "This identifier is already in use",
672
+ secretPlaceholder: "Paste the secret",
673
+ secretSet: "set",
674
+ keepSecret: "Leave blank to keep · current {now}",
675
+ secretRetype: "Enter the secret again",
676
+ endpointMoved: "Authority changed: to avoid sending the saved secret to a new address, enter the client secret again.",
677
+ ephemeralKey: "The data-protection master key is temporary, so secrets cannot be saved yet. Configure SmartAdmin:Security:DataProtection:Key and restart.",
678
+ ephemeralTitle: "The master key is temporary; saving is unavailable",
679
+ callback: "Callback URL",
680
+ callbackHint: "Enter this callback URL in the {name} console.",
681
+ idp: "identity provider",
682
+ callbackMissing: "SmartAdmin:ExternalAuth:CallbackBaseUrl is not set in production, so the callback URL cannot be computed.",
683
+ copyFailed: "Copy failed; select it manually",
684
+ test: "Test connection",
685
+ testing: "Testing…",
686
+ saved: "Saved",
687
+ clear: "Clear settings",
688
+ clearTitle: 'Clear the settings for "{name}"?',
689
+ clearConfirm: "After clearing, this sign-in option is unavailable and disappears from the login page. Accounts users have already bound to {name} are not deleted.",
690
+ cleared: "Cleared"
691
+ },
692
+ check: {
693
+ reachable: "Connectivity",
694
+ credentials: "Credentials",
695
+ agent: "AgentId",
696
+ appId: "AppId",
697
+ secret: "AppSecret",
698
+ discovery: "Discovery document",
699
+ issuer: "Issuer match",
700
+ endpoints: "Authorization and token endpoints",
701
+ clientSecret: "Client secret",
702
+ timeout: "Timeout",
703
+ error: "Error"
704
+ },
705
+ checkStatus: {
706
+ ok: "passed",
707
+ failed: "failed",
708
+ skipped: "not verified"
709
+ }
563
710
  },
564
711
  base: {
565
712
  siteTitle: "Site title",
566
- logo: "Logo URL",
567
- siteSubtitle: "Login subtitle",
713
+ siteSubtitle: "Subtitle",
568
714
  copyright: "Copyright",
569
715
  copyrightUrl: "Copyright link"
570
716
  },
717
+ login: {
718
+ language: "Login page language",
719
+ localeZh: "Chinese",
720
+ localeEn: "English",
721
+ showFeatures: "Show feature list",
722
+ headline: "Headline",
723
+ headlinePlaceholder: "Leave empty to use the built-in headline",
724
+ highlight: "Highlight",
725
+ highlightPlaceholder: "Word in the headline to highlight",
726
+ highlightHint: "Word in the headline shown in the accent color",
727
+ features: "Features",
728
+ featuresPlaceholder: "One per line, up to 5",
729
+ featuresHint: "One per line, up to 5",
730
+ highlightMissing: "Not in the headline; it will render as plain text",
731
+ tooManyFeatures: "At most 5 features"
732
+ },
571
733
  security: {
734
+ desc: "Sign-in protection, password rules, session length and rate limits. Takes effect on save.",
735
+ preview: "Rules users will meet",
736
+ groupLogin: "Sign-in protection",
737
+ groupSession: "Session",
738
+ groupRate: "Rate limit",
739
+ zeroNoLock: "0 = never lock",
740
+ zeroNever: "0 = never expires",
741
+ zeroOff: "0 = no limit",
742
+ unit: { times: "times", minutes: "min", days: "days", seconds: "s", chars: "chars" },
743
+ tryLabel: "Try a password",
744
+ tryMin: "At least {n} chars",
745
+ tryPass: "Accepted",
746
+ tryFail: "Rejected",
572
747
  loginLock: {
573
- title: "Login lockout",
574
- maxFailCount: "Max fail count",
575
- lockMinutes: "Lock minutes"
748
+ maxFailCount: "Lock after failures",
749
+ lockMinutes: "Lock duration"
576
750
  },
577
751
  password: {
578
- title: "Password complexity",
752
+ title: "Password",
579
753
  minLength: "Min length",
754
+ mustContain: "Must contain",
755
+ chipUpper: "A-Z",
756
+ chipLower: "a-z",
757
+ chipDigit: "0-9",
758
+ // @ 在 vue-i18n 里是链接语法,要用字面量插值转义
759
+ chipSpecial: "#{'@'}!",
580
760
  requireUpper: "Require uppercase",
581
761
  requireLower: "Require lowercase",
582
762
  requireDigit: "Require digit",
583
763
  requireSpecial: "Require special char",
584
- expireDays: "Password max age (days, 0 = never)",
585
- historyCount: "Password history count (0 = off)"
764
+ expireDays: "Max age",
765
+ historyCount: "No reuse of last",
766
+ forceChangeOnFirstLogin: "Change at first sign-in",
767
+ forceChangeOnFirstLoginHint: "New accounts only; resets still require a change"
586
768
  },
587
769
  session: {
588
- title: "Session lifetime",
589
- accessMinutes: "Access token (min)",
590
- refreshMinutes: "Refresh token (min)"
770
+ accessMinutes: "Access token lifetime",
771
+ refreshMinutes: "Stay signed in up to"
591
772
  },
592
773
  captcha: {
593
- title: "Login captcha",
594
- enabled: "Enable login captcha",
595
- type: "Captcha type",
596
- types: { char: "Characters", path: "Stroke (anti-scrape)", math: "Arithmetic" }
774
+ enabled: "Login captcha",
775
+ type: "Type",
776
+ types: { char: "Characters", path: "Stroke", math: "Arithmetic" }
597
777
  },
598
778
  totp: {
599
- title: "Authenticator (TOTP)",
600
- enabled: "Enable authenticator",
601
- requireForSuperAdmin: "Require authenticator for super admin",
779
+ enabled: "Authenticator (TOTP)",
780
+ requireForSuperAdmin: "Required for super admins",
602
781
  hint: "Toggles like login captcha — takes effect immediately. Per-user “require authenticator” only enforces at sign-in when this is on; users bind under Account security."
603
782
  },
604
783
  sms: {
605
- title: "SMS verification",
606
784
  hint: "The second factor only applies to users with a bound phone; in development, codes are printed to the backend log — production requires a real SMS provider (ISmsSender)."
607
785
  },
608
- mfa: { enabled: "Enable SMS second factor" },
609
- smsLogin: { enabled: "Enable SMS code sign-in" },
786
+ mfa: { enabled: "SMS second factor" },
787
+ smsLogin: { enabled: "SMS code sign-in" },
610
788
  rateLimit: {
611
- title: "Rate limiting",
612
- enabled: "Enable rate limiting",
613
- windowSeconds: "Window (seconds)",
614
- permitPerWindow: "Global requests / window",
615
- authPermitPerWindow: "Auth-endpoint requests / window"
789
+ enabled: "Enabled",
790
+ windowSeconds: "Window",
791
+ permitPerWindow: "Per source, at most",
792
+ authPermitPerWindow: "Sign-in endpoints, at most"
616
793
  },
617
794
  highSens: {
618
- title: "High-sensitivity permissions (custom)",
619
- hint: "Kernel defaults cannot be removed; only consumer custom codes can be added/deleted. Writes require recent reauth.",
620
795
  code: "Permission code",
621
796
  remark: "Remark",
622
- codePh: "e.g. POST:/api/v1/biz/order",
623
- remarkPh: "Optional remark",
797
+ codePh: "e.g. POST:/api/v1/biz/order/refund",
798
+ remarkPh: "Remark (optional)",
624
799
  codeRequired: "Permission code is required"
625
800
  }
626
801
  },
802
+ sensitive: {
803
+ desc: "Users must verify their identity again before calling these endpoints. Built-in ones cannot be removed; add your own business endpoints. Changes apply immediately.",
804
+ preview: "What users see when they call it",
805
+ previewTip: "Click a row to switch",
806
+ previewDoing: "You are about to call",
807
+ method: "Method",
808
+ path: "Endpoint",
809
+ builtin: "Built-in",
810
+ added: "Added, effective now",
811
+ removed: "Removed, effective now",
812
+ removeConfirm: 'Remove "{code}"? Calling it will no longer require re-verification.'
813
+ },
627
814
  upload: {
628
- title: "Upload limits",
629
- maxSizeMb: "Max size (MB)",
630
- allowedExtensions: "Allowed extensions",
631
- extPlaceholder: "Type an extension, e.g. .jpg",
632
- extTip: "With leading dot, lowercase; empty falls back to server default"
815
+ desc: "Size and type limits for every upload on the site. Takes effect on save.",
816
+ preview: "Live preview · upload box",
817
+ previewDrop: "Click or drop files here",
818
+ previewLimit: "Accepts {exts}, up to {mb} MB per file",
819
+ previewDefault: "server default types",
820
+ groupLimit: "Limits",
821
+ maxSizeMb: "Max file size",
822
+ allowedExtensions: "Allowed types",
823
+ extTip: "Empty = server default",
824
+ quickAdd: "Quick add",
825
+ preset: { images: "Images", docs: "Documents", archives: "Archives", clear: "Clear" },
826
+ fileOk: "OK",
827
+ fileBadExt: "{ext} not allowed",
828
+ fileTooBig: "Over {mb} MB",
829
+ fileDefault: "Per server default"
633
830
  }
634
831
  },
635
832
  // Dict management (master-detail: types on the left, items on the right)
@@ -1330,7 +1527,14 @@ const e = {
1330
1527
  csrfInvalid: "Request validation failed; refresh the page and try again",
1331
1528
  reauthRequired: "This action requires re-authentication",
1332
1529
  mfaBindPasswordRequired: "Verify your current password before binding an authenticator",
1333
- apiKeyInvalid: "API key missing or invalid"
1530
+ apiKeyInvalid: "API key missing or invalid",
1531
+ externalAuthTypeNotFound: "Sign-in type does not exist or its package is not installed",
1532
+ externalAuthCodeExists: "This code is already in use",
1533
+ externalAuthCodeInvalid: "Code is invalid or conflicts with a built-in sign-in method",
1534
+ externalAuthFieldMissing: "Required field missing: {field}",
1535
+ externalAuthDataProtectionKeyMissing: "No data-protection master key is configured, so third-party secrets cannot be stored safely. Set SmartAdmin:Security:DataProtection:Key first",
1536
+ externalAuthProviderNotFound: "This sign-in method is not configured",
1537
+ externalAuthEndpointBlocked: "This address is rejected by the outbound-request fence; check the scheme, host and network range"
1334
1538
  },
1335
1539
  perm: {
1336
1540
  denied: "Access denied",