discourse/app/assets/javascripts/admin/addon/templates/user-index.hbs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

777 lines
25 KiB
Handlebars
Raw Normal View History

<section class="details {{unless model.active "not-activated"}}">
<div class="user-controls">
{{#if model.canViewProfile}}
{{#link-to "user" model class="btn btn-default"}}
{{d-icon "user"}}
{{i18n "admin.user.show_public_profile"}}
{{/link-to}}
{{/if}}
{{#if model.can_view_action_logs}}
{{d-button
action=(action "viewActionLogs")
class="btn-default"
actionParam=model.username
2019-01-22 13:01:21 -05:00
icon="far-list-alt"
label="admin.user.action_logs"}}
{{/if}}
{{#if model.active}}
{{#if currentUser.admin}}
{{d-button
class="btn-default"
action=(action "logOut")
icon="power-off"
label="admin.user.log_out"}}
{{/if}}
{{/if}}
{{plugin-outlet
name="admin-user-controls-after"
args=(hash model=model)
DEV: Update default tagName and connectorTagName for plugin outlets (#13685) This commit should be a no-op for all existing core outlets. Outlets which are introduced by themes/plugins may see a change in behavior, and should follow the steps below if they want to maintain their previous behavior. `tagName="" connectorTagName=""` is almost always the correct choice for plugin outlets. 40eba8cd introduced a `noTags=true` shortcut which achieved this, and left a comment saying it should be the future default. This commit does exactly that. To avoid any breaking changes for plugins, all existing plugin outlets have been reviewed and adjusted by following this logic: 1) If `noTags=true`, remove the `noTags` parameter, and do not complete any further steps 2) If `tagName` is not specified, set `tagName="span"` (the previous default) 3) If `connectorTagName` is not specified, set `selectorTagName="div"` (the previous default) 4) If `tagName=""`, remove it 5) If `connectorTagName=""`, remove it The updates were accomplished with the help of a ruby script: ```ruby def removeAttr(tag, attribute) tag = tag.sub /\s#{attribute}="?\w*"? /, " " tag = tag.sub /\s#{attribute}="?\w*"?}}/, "}}" tag = tag.sub /^\s*#{attribute}="?\w*"?\n/, "" tag end files = Dir.glob("app/assets/javascripts/**/*.hbs") puts "Checking #{files.count} files..." files.each do |f| content = File.read(f) count = 0 edits = 0 content.gsub!(/{{\s*plugin-outlet.*?}}/m) do |match| count += 1 result = match noTags = result.include?("noTags=true") tagName = result[/tagName="(\w*)"/, 1] connectorTagName = result[/connectorTagName="(\w*)"/, 1] if noTags result = removeAttr(result, "noTags") else if connectorTagName == "" result = removeAttr(result, "connectorTagName") elsif connectorTagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} connectorTagName=\"div\"" } end if tagName == "" result = removeAttr(result, "tagName") elsif tagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} tagName=\"span\"" } end end edits += 1 if match != result result end puts "#{count} outlets, #{edits} edited -> #{f}" File.write(f, content) end ```
2022-01-06 15:38:17 -05:00
}}
</div>
<div class="display-row username">
{{admin-editable-field name="user.username.title"
value=model.username
action=(action "saveUsername")
editing=editingUsername}}
2013-02-05 14:16:51 -05:00
</div>
2013-04-20 01:34:11 -04:00
2019-05-24 13:39:16 -04:00
<div class="display-row name">
{{admin-editable-field name="user.name.title"
value=model.name
action=(action "saveName")
editing=editingName}}
</div>
{{plugin-outlet
name="admin-user-below-names"
args=(hash user=model)
DEV: Update default tagName and connectorTagName for plugin outlets (#13685) This commit should be a no-op for all existing core outlets. Outlets which are introduced by themes/plugins may see a change in behavior, and should follow the steps below if they want to maintain their previous behavior. `tagName="" connectorTagName=""` is almost always the correct choice for plugin outlets. 40eba8cd introduced a `noTags=true` shortcut which achieved this, and left a comment saying it should be the future default. This commit does exactly that. To avoid any breaking changes for plugins, all existing plugin outlets have been reviewed and adjusted by following this logic: 1) If `noTags=true`, remove the `noTags` parameter, and do not complete any further steps 2) If `tagName` is not specified, set `tagName="span"` (the previous default) 3) If `connectorTagName` is not specified, set `selectorTagName="div"` (the previous default) 4) If `tagName=""`, remove it 5) If `connectorTagName=""`, remove it The updates were accomplished with the help of a ruby script: ```ruby def removeAttr(tag, attribute) tag = tag.sub /\s#{attribute}="?\w*"? /, " " tag = tag.sub /\s#{attribute}="?\w*"?}}/, "}}" tag = tag.sub /^\s*#{attribute}="?\w*"?\n/, "" tag end files = Dir.glob("app/assets/javascripts/**/*.hbs") puts "Checking #{files.count} files..." files.each do |f| content = File.read(f) count = 0 edits = 0 content.gsub!(/{{\s*plugin-outlet.*?}}/m) do |match| count += 1 result = match noTags = result.include?("noTags=true") tagName = result[/tagName="(\w*)"/, 1] connectorTagName = result[/connectorTagName="(\w*)"/, 1] if noTags result = removeAttr(result, "noTags") else if connectorTagName == "" result = removeAttr(result, "connectorTagName") elsif connectorTagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} connectorTagName=\"div\"" } end if tagName == "" result = removeAttr(result, "tagName") elsif tagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} tagName=\"span\"" } end end edits += 1 if match != result result end puts "#{count} outlets, #{edits} edited -> #{f}" File.write(f, content) end ```
2022-01-06 15:38:17 -05:00
}}
{{#if canCheckEmails}}
<div class="display-row email">
<div class="field">{{i18n "user.email.primary"}}</div>
<div class="value">
{{#unless model.active}}
<div class="controls">{{i18n "admin.users.not_verified"}}</div>
{{/unless}}
{{#if model.email}}
<a href="mailto:{{model.email}}">{{model.email}}</a>
{{else}}
{{d-button
class="btn-default"
action=(route-action "checkEmail")
actionParam=model icon="far-envelope"
label="admin.users.check_email.text"
title="admin.users.check_email.title"}}
{{/if}}
</div>
<div class="controls">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
{{#if siteSettings.auth_overrides_email}}
{{i18n "user.email.auth_override_instructions"}}
{{else if model.email}}
{{html-safe (i18n "admin.user.visit_profile" url=preferencesPath)}}
{{/if}}
</div>
</div>
2013-04-20 01:34:11 -04:00
<div class="display-row secondary-emails">
<div class="field">{{i18n "user.email.secondary"}}</div>
2018-07-03 07:51:22 -04:00
<div class="value">
2018-07-03 07:51:22 -04:00
{{#if model.email}}
{{#if model.secondary_emails}}
<ul>
{{#each model.secondary_emails as |email| }}
<li><a href="mailto:{{email}}">{{email}}</a></li>
2018-07-03 07:51:22 -04:00
{{/each}}
</ul>
{{else}}
{{i18n "user.email.no_secondary"}}
2018-07-03 07:51:22 -04:00
{{/if}}
{{else}}
{{d-button action=(route-action "checkEmail")
class="btn-default"
2018-07-03 07:51:22 -04:00
actionParam=model
icon="far-envelope"
2018-07-03 07:51:22 -04:00
label="admin.users.check_email.text"
title="admin.users.check_email.title"}}
{{/if}}
</div>
<div class="controls">
{{#if model.email}}
{{#if model.secondary_emails}}
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
{{#if siteSettings.auth_overrides_email}}
{{i18n "user.email.auth_override_instructions"}}
{{else}}
{{html-safe (i18n "admin.user.visit_profile" url=preferencesPath)}}
{{/if}}
{{/if}}
{{/if}}
</div>
2018-07-03 07:51:22 -04:00
</div>
<div class="display-row bounce-score">
<div class="field"><a href={{model.bounceLink}}>{{i18n "admin.user.bounce_score"}}</a></div>
<div class="value">{{model.bounceScore}}</div>
<div class="controls">
{{#if model.canResetBounceScore}}
{{d-button
class="btn-default"
action=(action "resetBounceScore")
label="admin.user.reset_bounce_score.label"
title="admin.user.reset_bounce_score.title"}}
{{/if}}
{{model.bounceScoreExplanation}}
</div>
</div>
<div class="display-row associations">
<div class="field">{{i18n "user.associated_accounts.title"}}</div>
<div class="value">
{{#if associatedAccountsLoaded}}
{{associatedAccounts}}
{{else}}
{{d-button
class="btn-default"
action=(route-action "checkEmail")
actionParam=model icon="far-envelope"
label="admin.users.check_email.text"
title="admin.users.check_email.title"}}
{{/if}}
</div>
</div>
{{/if}}
<div class="display-row">
<div class="field">{{i18n "user.avatar.title"}}</div>
<div class="value">{{avatar model imageSize="large"}}</div>
<div class="controls">
{{html-safe (i18n "admin.user.visit_profile" url=preferencesPath)}}
</div>
2013-02-05 14:16:51 -05:00
</div>
2013-04-20 01:34:11 -04:00
<div class="display-row">
{{admin-editable-field name="user.title.title"
value=model.title
action=(action "saveTitle")
editing=editingTitle}}
</div>
<div class="display-row last-ip">
<div class="field">{{i18n "user.ip_address.title"}}</div>
<div class="value">{{model.ip_address}}</div>
<div class="controls">
{{#if currentUser.staff}}
{{ip-lookup ip=model.ip_address userId=model.id}}
{{/if}}
2013-02-05 14:16:51 -05:00
</div>
</div>
2013-04-20 01:34:11 -04:00
<div class="display-row registration-ip">
<div class="field">{{i18n "user.registration_ip_address.title"}}</div>
<div class="value">{{model.registration_ip_address}}</div>
<div class="controls">
{{#if currentUser.staff}}
{{ip-lookup ip=model.registration_ip_address userId=model.id}}
{{/if}}
</div>
</div>
{{#if showBadges}}
<div class="display-row">
<div class="field">{{i18n "admin.badges.title"}}</div>
<div class="value">
{{i18n "badges.badge_count" count=model.badge_count}}
</div>
<div class="controls">
{{#link-to "adminUser.badges" model class="btn btn-default"}}
{{d-icon "certificate"}}
{{i18n "admin.badges.edit_badges"}}
{{/link-to}}
</div>
</div>
{{/if}}
<div class="display-row">
<div class="field">{{i18n "user.second_factor.title"}}</div>
<div class="value">
{{#if model.second_factor_enabled}}
{{i18n "yes_value"}}
{{else}}
{{i18n "no_value"}}
{{/if}}
</div>
<div class="controls">
{{#if canDisableSecondFactor}}
{{d-button
class="btn-default"
action=(action "disableSecondFactor")
icon="unlock-alt"
label="user.second_factor.disable"}}
{{/if}}
</div>
</div>
2013-02-05 14:16:51 -05:00
</section>
{{#if userFields}}
<section class="details">
{{#each userFields as |uf|}}
<div class="display-row">
<div class="field">{{uf.name}}</div>
<div class="value">
2014-12-12 13:28:20 -05:00
{{#if uf.value}}
{{uf.value}}
{{else}}
&mdash;
{{/if}}
</div>
</div>
{{/each}}
</section>
{{/if}}
DEV: Update default tagName and connectorTagName for plugin outlets (#13685) This commit should be a no-op for all existing core outlets. Outlets which are introduced by themes/plugins may see a change in behavior, and should follow the steps below if they want to maintain their previous behavior. `tagName="" connectorTagName=""` is almost always the correct choice for plugin outlets. 40eba8cd introduced a `noTags=true` shortcut which achieved this, and left a comment saying it should be the future default. This commit does exactly that. To avoid any breaking changes for plugins, all existing plugin outlets have been reviewed and adjusted by following this logic: 1) If `noTags=true`, remove the `noTags` parameter, and do not complete any further steps 2) If `tagName` is not specified, set `tagName="span"` (the previous default) 3) If `connectorTagName` is not specified, set `selectorTagName="div"` (the previous default) 4) If `tagName=""`, remove it 5) If `connectorTagName=""`, remove it The updates were accomplished with the help of a ruby script: ```ruby def removeAttr(tag, attribute) tag = tag.sub /\s#{attribute}="?\w*"? /, " " tag = tag.sub /\s#{attribute}="?\w*"?}}/, "}}" tag = tag.sub /^\s*#{attribute}="?\w*"?\n/, "" tag end files = Dir.glob("app/assets/javascripts/**/*.hbs") puts "Checking #{files.count} files..." files.each do |f| content = File.read(f) count = 0 edits = 0 content.gsub!(/{{\s*plugin-outlet.*?}}/m) do |match| count += 1 result = match noTags = result.include?("noTags=true") tagName = result[/tagName="(\w*)"/, 1] connectorTagName = result[/connectorTagName="(\w*)"/, 1] if noTags result = removeAttr(result, "noTags") else if connectorTagName == "" result = removeAttr(result, "connectorTagName") elsif connectorTagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} connectorTagName=\"div\"" } end if tagName == "" result = removeAttr(result, "tagName") elsif tagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} tagName=\"span\"" } end end edits += 1 if match != result result end puts "#{count} outlets, #{edits} edited -> #{f}" File.write(f, content) end ```
2022-01-06 15:38:17 -05:00
{{plugin-outlet name="admin-user-details" tagName="span" connectorTagName="div" args=(hash model=model)}}
<section class="details">
<h1>{{i18n "admin.user.permissions"}}</h1>
2013-02-05 14:16:51 -05:00
{{#if siteSettings.must_approve_users}}
<div class="display-row">
<div class="field">{{i18n "admin.users.approved"}}</div>
<div class="value">
{{#if model.approved}}
{{i18n "admin.user.approved_by"}}
{{#link-to "adminUser" model.approvedBy}}
{{avatar model.approvedBy imageSize="small"}}
{{/link-to}}
{{#link-to "adminUser" model.approvedBy}}
{{model.approvedBy.username}}
{{/link-to}}
{{else}}
{{i18n "no_value"}}
{{/if}}
</div>
<div class="controls">
{{#if model.approved}}
{{i18n "admin.user.approve_success"}}
{{else}}
{{#if model.can_approve}}
{{d-button
class="btn-default"
action=(action "approve")
icon="check"
label="admin.user.approve"}}
{{/if}}
{{/if}}
</div>
2013-02-05 14:16:51 -05:00
</div>
{{/if}}
2013-02-05 14:16:51 -05:00
<div class="display-row">
<div class="field">{{i18n "admin.users.active"}}</div>
<div class="value">{{i18n-yes-no model.active}}</div>
<div class="controls">
{{#if model.active}}
{{#if model.can_deactivate}}
{{d-button
class="btn-default"
action=(action "deactivate")
label="admin.user.deactivate_account"}}
{{i18n "admin.user.deactivate_explanation"}}
{{/if}}
{{else}}
{{#if model.can_send_activation_email}}
{{d-button
class="btn-default"
action=(action "sendActivationEmail")
icon="envelope"
label="admin.user.send_activation_email"}}
{{/if}}
{{#if model.can_activate}}
{{d-button
class="btn-default"
action=(action "activate")
icon="check"
label="admin.user.activate"}}
{{/if}}
{{/if}}
</div>
</div>
2017-09-26 16:46:37 -04:00
<div class="display-row">
<div class="field">{{i18n "admin.user.staged"}}</div>
<div class="value">{{i18n-yes-no model.staged}}</div>
<div class="controls">{{i18n "admin.user.staged_explanation"}}</div>
2017-09-26 16:46:37 -04:00
</div>
{{#if currentUser.admin}}
<div class="display-row">
<div class="field">{{i18n "admin.api.active_keys"}}</div>
<div class="value">
{{model.api_key_count}}
</div>
<div class="controls">
{{d-button class="btn-default" href="/admin/api/keys" label="admin.api.manage_keys"}}
</div>
</div>
{{/if}}
2013-10-22 15:53:08 -04:00
<div class="display-row">
<div class="field">{{i18n "admin.user.admin"}}</div>
<div class="value">{{i18n-yes-no model.admin}}</div>
<div class="controls">
{{#if model.can_revoke_admin}}
{{d-button
class="btn-default"
action=(action "revokeAdmin")
icon="shield-alt"
label="admin.user.revoke_admin"}}
2013-02-05 14:16:51 -05:00
{{/if}}
{{#if model.can_grant_admin}}
{{d-button
class="btn-default grant-admin"
action=(action "grantAdmin")
icon="shield-alt"
label="admin.user.grant_admin"}}
{{/if}}
2013-02-05 14:16:51 -05:00
</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.moderator"}}</div>
<div class="value">{{i18n-yes-no model.moderator}}</div>
<div class="controls">
{{#if model.can_revoke_moderation}}
{{d-button
class="btn-default"
action=(action "revokeModeration")
icon="shield-alt"
label="admin.user.revoke_moderation"}}
{{/if}}
{{#if model.can_grant_moderation}}
{{d-button
class="btn-default"
action=(action "grantModeration")
icon="shield-alt"
label="admin.user.grant_moderation"}}
{{/if}}
</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "trust_level"}}</div>
<div class="value">
{{combo-box
content=site.trustLevels
nameProperty="detailedName"
value=model.trustLevel.id
onChange=(action (mut model.trust_level))
}}
{{#if model.dirty}}
<div>
{{d-button class="ok no-text" action=(action "saveTrustLevel") icon="check"}}
{{d-button class="cancel no-text" action=(action "restoreTrustLevel") icon="times"}}
</div>
{{/if}}
</div>
<div class="controls">
{{#if model.canLockTrustLevel}}
{{#if hasLockedTrustLevel}}
{{d-icon "lock" title="admin.user.trust_level_locked_tip"}}
{{d-button
class="btn-default"
action=(action "lockTrustLevel")
actionParam=false
label="admin.user.unlock_trust_level"}}
{{else}}
{{d-icon "unlock" title="admin.user.trust_level_unlocked_tip"}}
{{d-button
class="btn-default"
action=(action "lockTrustLevel")
actionParam=true
label="admin.user.lock_trust_level"}}
{{/if}}
{{/if}}
{{#if model.tl3Requirements}}
{{#link-to "adminUser.tl3Requirements" model class="btn btn-default"}}
{{i18n "admin.user.trust_level_3_requirements"}}
{{/link-to}}
{{/if}}
</div>
</div>
<div class="user-suspended display-row {{if model.suspended "highlight-danger"}}">
<div class="field">{{i18n "admin.user.suspended"}}</div>
<div class="value">
{{i18n-yes-no model.suspended}}
{{#if model.suspended}}
{{#unless model.suspendedForever}}
{{i18n "admin.user.suspended_until" until=model.suspendedTillDate}}
{{/unless}}
{{/if}}
</div>
<div class="controls">
{{#if model.suspended}}
2017-09-12 17:07:42 -04:00
{{d-button
class="btn-danger unsuspend-user"
action=(action "unsuspend")
2017-09-12 17:07:42 -04:00
icon="ban"
label="admin.user.unsuspend"}}
{{i18n "admin.user.suspended_explanation"}}
{{else}}
{{#if model.canSuspend}}
{{d-button
class="btn-danger suspend-user"
action=(action "showSuspendModal")
icon="ban"
label="admin.user.suspend"}}
{{i18n "admin.user.suspended_explanation"}}
{{/if}}
2013-02-05 14:16:51 -05:00
{{/if}}
</div>
</div>
{{#if model.suspended}}
<div class="display-row highlight-danger suspension-info">
<div class="field">{{i18n "admin.user.suspended_by"}}</div>
<div class="value">
{{#link-to "adminUser" model.suspendedBy}}
{{avatar model.suspendedBy imageSize="tiny"}}
{{/link-to}}
{{#link-to "adminUser" model.suspendedBy}}
{{model.suspendedBy.username}}
{{/link-to}}
</div>
<div class="controls">
<b>{{i18n "admin.user.suspend_reason"}}</b>:
<div class="full-reason">{{model.full_suspend_reason}}</div>
</div>
</div>
{{/if}}
<div class="display-row {{if model.silenced "highlight-danger"}}">
<div class="field">{{i18n "admin.user.silenced"}}</div>
<div class="value">
{{i18n-yes-no model.silenced}}
{{#if model.silenced}}
{{#unless model.silencedForever}}
{{i18n "admin.user.suspended_until" until=model.silencedTillDate}}
{{/unless}}
{{/if}}
</div>
<div class="controls">
2017-11-10 12:18:08 -05:00
{{#conditional-loading-spinner size="small" condition=model.silencingUser}}
{{#if model.silenced}}
{{d-button
class="btn-danger unsilence-user"
action=(action "unsilence")
icon="microphone-slash"
label="admin.user.unsilence"}}
{{i18n "admin.user.silence_explanation"}}
{{else}}
{{d-button
class="btn-danger silence-user"
action=(action "showSilenceModal")
icon="microphone-slash"
label="admin.user.silence"}}
{{i18n "admin.user.silence_explanation"}}
{{/if}}
{{/conditional-loading-spinner}}
</div>
</div>
{{#if model.silenced}}
<div class="display-row highlight-danger silence-info">
<div class="field">{{i18n "admin.user.silenced_by"}}</div>
<div class="value">
{{#link-to "adminUser" model.silencedBy}}
{{avatar model.silencedBy imageSize="tiny"}}
{{/link-to}}
{{#link-to "adminUser" model.silencedBy}}
{{model.silencedBy.username}}
{{/link-to}}
</div>
<div class="controls">
<b>{{i18n "admin.user.silence_reason"}}</b>:
<div class="full-reason">{{model.silence_reason}}</div>
</div>
</div>
{{/if}}
{{#if model.tl3_requirements.penalty_counts.total}}
<div class="display-row clear-penalty-history">
<div class="field">{{i18n "admin.user.penalty_count"}}</div>
<div class="value">{{model.tl3_requirements.penalty_counts.total}}</div>
{{#if currentUser.admin}}
<div class="controls">
{{d-button label="admin.user.clear_penalty_history.title"
class="btn-default"
icon="times"
action=(action "clearPenaltyHistory")}}
{{i18n "admin.user.clear_penalty_history.description"}}
</div>
{{/if}}
</div>
{{/if}}
2013-02-05 14:16:51 -05:00
</section>
{{#if currentUser.admin}}
<section class="details">
<h1>{{i18n "admin.groups.title"}}</h1>
<div class="display-row">
<div class="field">{{i18n "admin.groups.automatic"}}</div>
<div class="value">{{html-safe automaticGroups}}</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.groups.custom"}}</div>
<div class="value">
{{group-chooser
content=availableGroups
value=customGroupIdsBuffer
labelProperty="name"
onChange=(action (mut customGroupIdsBuffer))
}}
</div>
{{#if customGroupsDirty}}
<div class="controls">
{{d-button icon="check" class="ok" action=(action "saveCustomGroups")}}
{{d-button icon="times" class="cancel" action=(action "resetCustomGroups")}}
</div>
{{/if}}
</div>
{{#if model.customGroups}}
<div class="display-row">
<div class="field">{{i18n "admin.groups.primary"}}</div>
<div class="value">
{{combo-box
content=model.customGroups
value=model.primary_group_id
onChange=(action (mut model.primary_group_id))
options=(hash
none="admin.groups.no_primary"
)
}}
</div>
{{#if primaryGroupDirty}}
<div class="controls">
{{d-button icon="check" class="ok" action=(action "savePrimaryGroup")}}
{{d-button icon="times" class="cancel" action=(action "resetPrimaryGroup")}}
</div>
{{/if}}
</div>
{{/if}}
</section>
{{/if}}
<section class="details">
<h1>{{i18n "admin.user.activity"}}</h1>
2013-02-05 14:16:51 -05:00
<div class="display-row">
<div class="field">{{i18n "created"}}</div>
<div class="value">{{format-date model.created_at leaveAgo="true"}}</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "admin.users.last_emailed"}}</div>
<div class="value">{{format-date model.last_emailed_at}}</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "last_seen"}}</div>
<div class="value">{{format-date model.last_seen_at leaveAgo="true"}}</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.like_count"}}</div>
<div class="value">{{model.like_given_count}} / {{model.like_count}}</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.topics_entered"}}</div>
<div class="value">{{model.topics_entered}}</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.post_count"}}</div>
<div class="value">{{model.post_count}}</div>
<div class="controls">
{{#if model.can_delete_all_posts}}
{{#if model.post_count}}
{{d-button
class="btn-danger"
action=(action "showDeletePostsConfirmation")
icon="far-trash-alt"
label="admin.user.delete_posts.button"}}
{{/if}}
{{else}}
{{deleteAllPostsExplanation}}
{{/if}}
</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.posts_read_count"}}</div>
<div class="value">{{model.posts_read_count}}</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.warnings_received_count"}}</div>
<div class="value">{{model.warnings_received_count}}</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.flags_given_received_count"}}</div>
<div class="value">
{{model.flags_given_count}} / {{model.flags_received_count}}
</div>
<div class="controls">
{{#if model.flags_received_count}}
{{#link-to "review" (query-params username=model.username type="ReviewableFlaggedPost" status="all") class="btn"}}
{{i18n "admin.user.show_flags_received"}}
{{/link-to}}
{{/if}}
</div>
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.private_topics_count"}}</div>
<div class="value">{{model.private_topics_count}}</div>
2013-02-05 14:16:51 -05:00
</div>
<div class="display-row">
<div class="field">{{i18n "admin.user.time_read"}}</div>
<div class="value">{{format-duration model.time_read}}</div>
</div>
<div class="display-row">
<div class="field">{{i18n "user.invited.days_visited"}}</div>
<div class="value">{{html-safe model.days_visited}}</div>
</div>
<div class="display-row post-edits-count">
<div class="field">{{i18n "admin.user.post_edits_count" }}</div>
<div class="value">
{{if (gt model.post_edits_count 0) model.post_edits_count "0"}}
</div>
<div class="controls">
{{#if (gt model.post_edits_count 0) }}
{{#link-to "adminReports.show" "post_edits" (query-params filters=postEditsByEditorFilter) class="btn btn-icon"}}
{{d-icon "far-eye"}}
{{i18n "admin.user.view_edits"}}
{{/link-to}}
{{/if}}
</div>
</div>
2013-02-05 14:16:51 -05:00
</section>
{{#if model.single_sign_on_record}}
<section class="details">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<h1>{{i18n "admin.user.discourse_connect.title"}}</h1>
2014-08-22 20:34:48 -04:00
{{#with model.single_sign_on_record as |sso|}}
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.external_id"}}</div>
<div class="value">{{sso.external_id}}</div>
{{#if model.can_delete_sso_record}}
<div class="controls">
{{d-button
class="btn-danger"
action=(action "deleteSSORecord")
icon="far-trash-alt"
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
label="admin.user.discourse_connect.delete_sso_record"
}}
</div>
{{/if}}
</div>
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.external_username"}}</div>
<div class="value">{{sso.external_username}}</div>
</div>
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.external_name"}}</div>
<div class="value">{{sso.external_name}}</div>
</div>
{{#if canAdminCheckEmails}}
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.external_email"}}</div>
{{#if ssoExternalEmail}}
<div class="value">{{ssoExternalEmail}}</div>
{{else}}
{{d-button
class="btn-default"
action=(action "checkSsoEmail")
actionParam=model icon="far-envelope"
label="admin.users.check_email.text"
title="admin.users.check_email.title"}}
{{/if}}
</div>
{{/if}}
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.external_avatar_url"}}</div>
<div class="value">{{sso.external_avatar_url}}</div>
2014-08-22 20:34:48 -04:00
</div>
{{#if canAdminCheckEmails}}
<div class="display-row">
FEATURE: Rename 'Discourse SSO' to DiscourseConnect (#11978) The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense. This commit aims to: - Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_` - Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices - Copy `site_settings` database records to the new names - Rename relevant translation keys - Update relevant translations This commit does **not** aim to: - Rename any Ruby classes or methods. This might be done in a future commit - Change any URLs. This would break existing integrations - Make any changes to the protocol. This would break existing integrations - Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately The risks are: - There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical. - If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working. A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
2021-02-08 05:04:33 -05:00
<div class="field">{{i18n "admin.user.discourse_connect.last_payload"}}</div>
{{#if ssoLastPayload}}
<div class="value">
{{#each ssoPayload as |line|}}
{{line}}<br>
{{/each}}
</div>
{{else}}
{{d-button
class="btn-default"
action=(action "checkSsoPayload")
actionParam=model icon="far-list-alt"
label="admin.users.check_sso.text"
title="admin.users.check_sso.title"}}
{{/if}}
</div>
{{/if}}
2014-08-22 20:34:48 -04:00
{{/with}}
</section>
{{/if}}
DEV: Update default tagName and connectorTagName for plugin outlets (#13685) This commit should be a no-op for all existing core outlets. Outlets which are introduced by themes/plugins may see a change in behavior, and should follow the steps below if they want to maintain their previous behavior. `tagName="" connectorTagName=""` is almost always the correct choice for plugin outlets. 40eba8cd introduced a `noTags=true` shortcut which achieved this, and left a comment saying it should be the future default. This commit does exactly that. To avoid any breaking changes for plugins, all existing plugin outlets have been reviewed and adjusted by following this logic: 1) If `noTags=true`, remove the `noTags` parameter, and do not complete any further steps 2) If `tagName` is not specified, set `tagName="span"` (the previous default) 3) If `connectorTagName` is not specified, set `selectorTagName="div"` (the previous default) 4) If `tagName=""`, remove it 5) If `connectorTagName=""`, remove it The updates were accomplished with the help of a ruby script: ```ruby def removeAttr(tag, attribute) tag = tag.sub /\s#{attribute}="?\w*"? /, " " tag = tag.sub /\s#{attribute}="?\w*"?}}/, "}}" tag = tag.sub /^\s*#{attribute}="?\w*"?\n/, "" tag end files = Dir.glob("app/assets/javascripts/**/*.hbs") puts "Checking #{files.count} files..." files.each do |f| content = File.read(f) count = 0 edits = 0 content.gsub!(/{{\s*plugin-outlet.*?}}/m) do |match| count += 1 result = match noTags = result.include?("noTags=true") tagName = result[/tagName="(\w*)"/, 1] connectorTagName = result[/connectorTagName="(\w*)"/, 1] if noTags result = removeAttr(result, "noTags") else if connectorTagName == "" result = removeAttr(result, "connectorTagName") elsif connectorTagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} connectorTagName=\"div\"" } end if tagName == "" result = removeAttr(result, "tagName") elsif tagName.nil? result = result.sub(/name="[\w-]+"/) { |m| "#{m} tagName=\"span\"" } end end edits += 1 if match != result result end puts "#{count} outlets, #{edits} edited -> #{f}" File.write(f, content) end ```
2022-01-06 15:38:17 -05:00
{{plugin-outlet name="after-user-details" tagName="span" connectorTagName="div" args=(hash model=model)}}
2018-04-16 14:41:03 -04:00
<section>
<hr>
2015-03-10 13:06:08 -04:00
<div class="pull-right">
{{#if model.active}}
{{#if model.can_impersonate}}
{{d-button
class="btn-danger btn-impersonate"
action=(action "impersonate")
icon="crosshairs"
label="admin.impersonate.title"
title="admin.impersonate.help"}}
{{/if}}
{{/if}}
{{#if model.can_be_anonymized}}
2015-03-10 13:06:08 -04:00
{{d-button label="admin.user.anonymize"
icon="exclamation-triangle"
class="btn-danger btn-anonymize"
action=(action "anonymize")}}
{{/if}}
2015-03-10 13:06:08 -04:00
{{#if model.canBeDeleted}}
2015-03-10 13:06:08 -04:00
{{d-button label="admin.user.delete"
icon="trash-alt"
class="btn-danger btn-user-delete"
action=(action "destroy")}}
{{/if}}
{{#if model.can_be_merged}}
{{d-button label="admin.user.merge.button"
icon="arrows-alt-h"
class="btn-danger btn-user-merge"
action=(action "promptTargetUser")}}
{{/if}}
2015-03-10 13:06:08 -04:00
</div>
{{#if deleteExplanation}}
<div class="clearfix"></div>
<br>
<div class="pull-right">
{{d-icon "exclamation-triangle"}} {{deleteExplanation}}
</div>
{{/if}}
</section>
<div class="clearfix"></div>