Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/app/playwright/40-admin/access-to-admin-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ test('admin/security is successfully loaded', async({ page }) => {
await page.goto('/admin/security');

await expect(page.getByTestId('admin-security')).toBeVisible();
await expect(page.locator('#isShowRestrictedByOwner')).not.toBeChecked();
await expect(page.locator('#isShowRestrictedByGroup')).not.toBeChecked();
await expect(page.locator('#isShowRestrictedByOwner')).toHaveText('Always displayed');
await expect(page.locator('#isShowRestrictedByGroup')).toHaveText('Always displayed');
});

test('admin/markdown is successfully loaded', async({ page }) => {
Expand Down
1 change: 0 additions & 1 deletion apps/app/public/static/locales/en_US/admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"readonly_users_access": "Read only users' access",
"always_hidden": "Always hidden",
"always_displayed": "Always displayed",
"displayed_or_hidden": "Hidden / Displayed",
"Fixed by env var": "This is fixed by the env var <code>{{key}}={{value}}</code>.",
"register_limitation": "Register limitation",
"register_limitation_desc": "Restriction of new users' registration",
Expand Down
1 change: 0 additions & 1 deletion apps/app/public/static/locales/fr_FR/admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"readonly_users_access": "Accès des utilisateurs lecture seule",
"always_hidden": "Toujours caché",
"always_displayed": "Toujours affiché",
"displayed_or_hidden": "Caché / Affiché",
"Fixed by env var": "Configuré par la variable d'environnement <code>{{key}}={{value}}</code>.",
"register_limitation": "Paramètres d'inscription",
"register_limitation_desc": "Restreindre l'inscription de nouveaux utilisateurs",
Expand Down
41 changes: 20 additions & 21 deletions apps/app/public/static/locales/ja_JP/admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,21 @@
"Execute": "実行",
"last_login": "最終ログイン",
"wiki_management_homepage": "Wiki管理トップ",
"public": "公開",
"anyone_with_the_link": "リンクを知っている人のみ",
"public": "「公開」のページ",
"anyone_with_the_link": "リンクを知っている人のみ」のページ",
"specified_users": "特定ユーザーのみ",
"only_me": "自分のみ",
"only_inside_the_group": "特定グループのみ",
"only_me": "自分のみ」のページ",
"only_inside_the_group": "特定グループのみ」のページ",
"optional": "オプション",
"days": "日",
"security_settings": {
"security_settings": "セキュリティ設定",
"scope_of_page_disclosure": "ページの公開範囲",
"set_point": "設定値",
"Guest Users Access":"ゲストユーザーのアクセス",
"Guest Users Access": "ゲストユーザーのアクセス",
"readonly_users_access": "閲覧のみユーザーのアクセス",
"always_hidden": "非表示 (固定)",
"always_displayed": "表示 (固定)",
"displayed_or_hidden": "非表示 / 表示",
"always_hidden": "表示しない",
"always_displayed": "表示する",
Comment on lines +29 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"displayed" と "hidden" の値と同じものなので、それらを使うようにして良さそう

"Fixed by env var": "環境変数 <code>{{forcewikimode}}={{wikimode}}</code> により固定されています。",
"register_limitation": "登録の制限",
"register_limitation_desc": "新しいユーザーを登録する方法を制限します。",
Expand Down Expand Up @@ -73,7 +72,7 @@
"forced_update_desc": "設定が強制変更されました。前回の設定: ",
"page_delete_rights_caution": "「(子孫ページを含む)ゴミ箱に入れる操作 / 完全に削除する」の権限は、「ゴミ箱に入れる操作 / 完全に削除する」よりも強い権限になるように強制されます。 <br><br> 管理者のみ可能 > 管理者とページ作者が可能 > 誰でも可能",
"Authentication mechanism settings": "認証機構設定",
"setup_is_not_yet_complete":"セットアップはまだ完了してません",
"setup_is_not_yet_complete": "セットアップはまだ完了してません",
"xss_prevent_setting": "XSS(Cross Site Scripting)対策設定",
"xss_prevent_setting_link": "マークダウン設定ページに移動",
"callback_URL": "コールバックURL",
Expand Down Expand Up @@ -107,9 +106,9 @@
"closed": "非公開 (登録には管理者による招待が必要)"
},
"share_link_management": "共有リンク管理",
"No_share_links":"共有リンクが存在しません",
"share_link_notice":"共有リンクを全て削除します",
"delete_all_share_links":"全ての共有リンクを削除します",
"No_share_links": "共有リンクが存在しません",
"share_link_notice": "共有リンクを全て削除します",
"delete_all_share_links": "全ての共有リンクを削除します",
"share_link_rights": "シェアリンクの権限",
"enable_link_sharing": "リンクのシェアを許可",
"all_share_links": "全てのシェアリンク",
Expand Down Expand Up @@ -512,13 +511,13 @@
"show_page_side_authors": "作成者・更新者を目次上部に常時表示する",
"show_page_side_authors_desc": "ページサイドバーの目次上部に作成者と最終更新者の情報を表示します。"
},
"presentation":"プレゼンテーション",
"presentation_options":{
"presentation": "プレゼンテーション",
"presentation_options": {
"enable_marp": "Marp を有効化する",
"enable_marp_desc": "プレゼンテーション表示に Marp を利用できるようになります。ただし、XSS に対して脆弱になる恐れがあります。",
"marp_official_site": "参考:Marp 公式サイト",
"marp_official_site_link": "https://marp.app",
"marp_in_growi" : "参考:GROWI Docs - Marp でスライドを作成する",
"marp_in_growi": "参考:GROWI Docs - Marp でスライドを作成する",
"marp_in_growi_link": "https://docs.growi.org/ja/guide/features/marp.html"
},
"custom_title": "カスタム Title",
Expand All @@ -532,7 +531,7 @@
"write_css": " システム全体に適用されるCSSを記述できます。",
"ctrl_space": "Ctrl+Space でコード補完",
"custom_script": "カスタムスクリプト",
"custom_presentation":"プレゼンテーション",
"custom_presentation": "プレゼンテーション",
"write_java": "システム全体に適用されるJavaScriptを記述できます。",
"reflect_change": "変更の反映はページの更新が必要です。",
"custom_logo": "カスタムロゴ",
Expand All @@ -541,7 +540,7 @@
"current_logo": "現在のロゴ",
"upload_new_logo": "新しいロゴをアップロードする",
"delete_logo": "ロゴを削除"
},
},
"importer_management": {
"import_data": "データインポート",
"article": "記事",
Expand Down Expand Up @@ -681,7 +680,7 @@
"delete": "削除",
"integration_procedure": "連携手順",
"custom_bot_without_proxy_settings": "Custom Bot without proxy 設定",
"integration_failed":"連携に失敗しました",
"integration_failed": "連携に失敗しました",
"reset": "リセット",
"reset_all_settings": "全ての設定をリセット",
"delete_slackbot_settings": "Slack Bot 設定を削除する",
Expand Down Expand Up @@ -728,7 +727,7 @@
"allow_specified_long": "特定のチャンネルを許可 (テキストボックスに入力されたチャンネルのみ許可されます)",
"test_connection": "連携状況のテストをする",
"test_connection_by_pressing_button": "以下のテストボタンを押して、Slack連携が完了しているかの確認をしましょう",
"test_connection_only_public_channel":"連携テストは public チャンネルで確認してください",
"test_connection_only_public_channel": "連携テストは public チャンネルで確認してください",
"error_check_logs_below": "エラーが発生しました。下記のログを確認してください。",
"send_message_to_slack_work_space": "Slack ワークスペースに送信しました",
"add_slack_workspace": "Slackワークスペースを追加"
Expand All @@ -752,7 +751,7 @@
}
},
"slack_integration_legacy": {
"slack_integration_legacy": "Slack連携 (レガシー)",
"slack_integration_legacy": "Slack連携 (レガシー)",
"alert_disabled": "<a href='/admin/slack-integration'>新しい設定</a>が有効になっているため、この 'Slack連携 (レガシー)' は現在無効になっています。",
"alert_deplicated": "この 'Slack連携 (レガシー)' は将来廃止されます。代わりに<a href='/admin/slack-integration'>新しいSlack連携機能</a>を利用してください。"
},
Expand Down Expand Up @@ -989,7 +988,7 @@
"ADMIN_SITE_URL_UPDATE": "サイトURL設定の更新",
"ADMIN_MAIL_SMTP_UPDATE": "メール設定(SMTP)の更新",
"ADMIN_MAIL_SES_UPDATE": "メール設定(SES)の更新",
"ADMIN_MAIL_TEST_SUBMIT" : "テストメールの送信",
"ADMIN_MAIL_TEST_SUBMIT": "テストメールの送信",
"ADMIN_FILE_UPLOAD_CONFIG_UPDATE": "ファイルアップロード設定の更新",
"ADMIN_PLUGIN_UPDATE": "プラグイン設定の更新",
"ADMIN_MAINTENANCEMODE_ENABLED": "メンテナンスモードの開始",
Expand Down
1 change: 0 additions & 1 deletion apps/app/public/static/locales/zh_CN/admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"set_point": "设定值",
"always_displayed": "始终显示",
"always_hidden": "总是隐藏",
"displayed_or_hidden": "隐藏 / 显示",
"Guest Users Access": "来宾用户访问",
"readonly_users_access": "只浏览用户的访问",
"Fixed by env var": "这是由env var<code>%s=%s</code>修复的。",
Expand Down
146 changes: 94 additions & 52 deletions apps/app/src/client/components/Admin/Security/SecuritySetting.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class SecuritySetting extends React.Component {
onClick={() => this.setExpantOtherDeleteOptionsState(deletionType, !expantDeleteOptionsState)}
>
<span className={`material-symbols-outlined me-1 ${expantDeleteOptionsState ? 'rotate-90' : ''}`}>navigate_next</span>
{ t('security_settings.other_options') }
{t('security_settings.other_options')}
</button>
<Collapse isOpen={expantDeleteOptionsState}>
<div className="pb-4">
Expand All @@ -308,7 +308,7 @@ class SecuritySetting extends React.Component {
<span dangerouslySetInnerHTML={{ __html: t('security_settings.page_delete_rights_caution') }} />
</span>
</p>
{ this.previousPageRecursiveAuthorityState(deletionType) !== null && (
{this.previousPageRecursiveAuthorityState(deletionType) !== null && (
<div className="mb-3">
<strong>
{t('security_settings.forced_update_desc')}
Expand Down Expand Up @@ -356,60 +356,102 @@ class SecuritySetting extends React.Component {
</div>
)}

<h4 className="mt-4">{ t('security_settings.page_list_and_search_results') }</h4>
<div className="row justify-content-md-center">
<table className="table table-bordered col-lg-9 mb-5">
<thead>
<tr>
<th scope="col">{ t('security_settings.scope_of_page_disclosure') }</th>
<th scope="col">{ t('security_settings.set_point') }</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{ t('public') }</th>
<td><span className="material-symbols-outlined text-success me-1">check_circle</span>{ t('security_settings.always_displayed') }</td>
</tr>
<tr>
<th scope="row">{ t('anyone_with_the_link') }</th>
<td><span className="material-symbols-outlined text-danger me-1">cancel</span>{ t('security_settings.always_hidden') }</td>
</tr>
<tr>
<th scope="row">{ t('only_me') }</th>
<td>
<div className="form-check form-switch form-check-success">
<input
type="checkbox"
className="form-check-input"
<h4 className="alert-anchor border-bottom mt-4">{t('security_settings.page_list_and_search_results')}</h4>
<div className="row mb-4">
<div className="col-md-10">
<div className="row">

{/* Left Column: Labels */}
<div className="col-5 d-flex flex-column align-items-end p-4">
<div className="fw-bold mb-4">{t('public')}</div>
<div className="fw-bold mb-4">{t('anyone_with_the_link')}</div>
<div className="fw-bold mb-4">{t('only_me')}</div>
<div className="fw-bold">{t('only_inside_the_group')}</div>
</div>

{/* Right Column: Content */}
<div className="col-7 d-flex flex-column align-items-start pt-4 pb-4">
<div className="mb-4 d-flex align-items-center">
<span className="material-symbols-outlined text-success me-1"></span>
{t('security_settings.always_displayed')}
</div>
<div className="mb-3 d-flex align-items-center">
<span className="material-symbols-outlined text-danger me-1"></span>
{t('security_settings.always_hidden')}
</div>

{/* Owner Restriction Dropdown */}
<div className="mb-3">
<div className="dropdown">
<button
className="btn btn-outline-secondary dropdown-toggle text-end col-12 col-md-auto"
type="button"
id="isShowRestrictedByOwner"
checked={!adminGeneralSecurityContainer.state.isShowRestrictedByOwner}
onChange={() => { adminGeneralSecurityContainer.switchIsShowRestrictedByOwner() }}
/>
<label className="form-label form-check-label" htmlFor="isShowRestrictedByOwner">
{t('security_settings.displayed_or_hidden')}
</label>
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
>
<span className="float-start">
{adminGeneralSecurityContainer.state.currentOwnerRestrictionDisplayMode === 'Displayed' && t('security_settings.always_displayed')}
{adminGeneralSecurityContainer.state.currentOwnerRestrictionDisplayMode === 'Hidden' && t('security_settings.always_hidden')}
</span>
</button>
<div className="dropdown-menu" aria-labelledby="isShowRestrictedByOwner">
<button
className="dropdown-item"
type="button"
onClick={() => { adminGeneralSecurityContainer.changeOwnerRestrictionDisplayMode('Displayed') }}
>
{t('security_settings.always_displayed')}
</button>
<button
className="dropdown-item"
type="button"
onClick={() => { adminGeneralSecurityContainer.changeOwnerRestrictionDisplayMode('Hidden') }}
>
{t('security_settings.always_hidden')}
</button>
</div>
</div>
</td>
</tr>
<tr>
<th scope="row">{ t('only_inside_the_group') }</th>
<td>
<div className="form-check form-switch form-check-success">
<input
type="checkbox"
className="form-check-input"
</div>

{/* Group Restriction Dropdown */}
<div className="">
<div className="dropdown">
<button
className="btn btn-outline-secondary dropdown-toggle text-end col-12 col-md-auto"
type="button"
id="isShowRestrictedByGroup"
checked={!adminGeneralSecurityContainer.state.isShowRestrictedByGroup}
onChange={() => { adminGeneralSecurityContainer.switchIsShowRestrictedByGroup() }}
/>
<label className="form-label form-check-label" htmlFor="isShowRestrictedByGroup">
{t('security_settings.displayed_or_hidden')}
</label>
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
>
<span className="float-start">
{adminGeneralSecurityContainer.state.currentGroupRestrictionDisplayMode === 'Displayed' && t('security_settings.always_displayed')}
{adminGeneralSecurityContainer.state.currentGroupRestrictionDisplayMode === 'Hidden' && t('security_settings.always_hidden')}
</span>
</button>
<div className="dropdown-menu" aria-labelledby="isShowRestrictedByGroup">
<button
className="dropdown-item"
type="button"
onClick={() => { adminGeneralSecurityContainer.changeGroupRestrictionDisplayMode('Displayed') }}
>
{t('security_settings.always_displayed')}
</button>
<button
className="dropdown-item"
type="button"
onClick={() => { adminGeneralSecurityContainer.changeGroupRestrictionDisplayMode('Hidden') }}
>
{t('security_settings.always_hidden')}
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

<h4 className="mb-3">{t('security_settings.page_access_rights')}</h4>
Expand Down
Loading
Loading