Skip to content

Commit

Permalink
Logout from all devices link (#8630)
Browse files Browse the repository at this point in the history
* Logout from all devices link

* Use v-text everywhere

* Use config, add unittest, update snapshots

* Add unittest, update snapshots

* Add changelog

* Address PR issues

* Update snapshot

* Update config manager

* Remove unused icon
  • Loading branch information
lookacat committed Mar 23, 2023
1 parent 570eb21 commit 912563b
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 18 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-add-logout-url
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Add logout url

We've added "Logout from active devices" in the account settings

https://github.com/owncloud/web/pull/8630
https://github.com/owncloud/web/issues/8609
9 changes: 9 additions & 0 deletions packages/web-pkg/src/configuration/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ export class ConfigurationManager {
this.oidcConfiguration = rawConfig.openIdConnect
? (rawConfig.openIdConnect as OIDCConfiguration)
: null
this.logoutUrl = rawConfig.options?.logoutUrl
}

set logoutUrl(url: string) {
this.optionsConfiguration.logoutUrl = url
}

get logoutUrl(): string {
return this.optionsConfiguration.logoutUrl
}

set serverUrl(url: string) {
Expand Down
1 change: 1 addition & 0 deletions packages/web-pkg/src/configuration/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface RoutingOptionsConfiguration {

export interface OptionsConfiguration {
routing?: RoutingOptionsConfiguration
logoutUrl?: string
}

export interface OAuth2Configuration {
Expand Down
46 changes: 34 additions & 12 deletions packages/web-runtime/src/pages/account.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,46 @@
</oc-button>
</div>
</div>
<h2 v-translate class="oc-text-bold oc-mb">Account Information</h2>
<h2 class="oc-text-bold oc-mb" v-text="$gettext('Account Information')" />
<dl class="account-page-info oc-flex oc-flex-wrap">
<div class="account-page-info-username oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Username</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Username')" />
<dd>
{{ user.username || user.id }}
</dd>
</div>
<div v-if="user.username && user.id" class="account-page-info-userid">
<dt v-translate class="oc-text-normal oc-text-muted">User ID</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('User ID')" />
<dd>
{{ user.id }}
</dd>
</div>
<div class="account-page-info-displayname oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Display name</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Display name')" />
<dd>
{{ user.displayname }}
</dd>
</div>
<div class="account-page-info-email oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Email</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Email')" />
<dd>
<template v-if="user.email">{{ user.email }}</template>
<span v-else v-translate>No email has been set up</span>
<span v-else v-text="$gettext('No email has been set up')" />
</dd>
</div>
<div class="account-page-info-groups oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Group memberships</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Group memberships')" />
<dd data-testid="group-names">
<span v-if="groupNames">{{ groupNames }}</span>
<span v-else v-translate data-testid="group-names-empty"
>You are not part of any group</span
>
<span
v-else
data-testid="group-names-empty"
v-text="$gettext('You are not part of any group')"
/>
</dd>
</div>
<div v-if="isLanguageSupported" class="account-page-info-language oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Language</dt>
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Language')" />
<dd data-testid="language">
<oc-select
v-if="languageOptions"
Expand All @@ -78,6 +80,20 @@
/>
</dd>
</div>
<div v-if="logoutUrl" class="account-page-logout-all-devices oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Logout from active devices')" />
<dd data-testid="logout">
<oc-button
appearance="raw"
type="a"
:href="logoutUrl"
target="_blank"
data-testid="account-page-logout-url-btn"
>
<span v-text="$gettext('Account security')" />
</oc-button>
</dd>
</div>
</dl>
</main>
</template>
Expand All @@ -97,6 +113,7 @@ import axios from 'axios'
import { v4 as uuidV4 } from 'uuid'
import { useGettext } from 'vue3-gettext'
import { setCurrentLanguage } from 'web-runtime/src/helpers/language'
import { configurationManager } from 'web-pkg/src/configuration'
export default defineComponent({
name: 'Personal',
Expand Down Expand Up @@ -201,6 +218,10 @@ export default defineComponent({
return unref(user).groups.join(', ')
})
const logoutUrl = computed(() => {
return configurationManager.logoutUrl
})
onMounted(() => {
if (unref(isLanguageSupported)) {
loadAccountBundleTask.perform()
Expand All @@ -216,7 +237,8 @@ export default defineComponent({
isChangePasswordEnabled,
isLanguageSupported,
groupNames,
user
user,
logoutUrl
}
},
data() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,33 @@
exports[`account page account information displays basic user information 1`] = `
<dl class="account-page-info oc-flex oc-flex-wrap">
<div class="account-page-info-username oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" data-current-language="en" data-msgid="Username">Username</dt>
<dt class="oc-text-normal oc-text-muted">Username</dt>
<dd></dd>
</div>
<!--v-if-->
<div class="account-page-info-displayname oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" data-current-language="en" data-msgid="Display name">Display name</dt>
<dt class="oc-text-normal oc-text-muted">Display name</dt>
<dd></dd>
</div>
<div class="account-page-info-email oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" data-current-language="en" data-msgid="Email">Email</dt>
<dt class="oc-text-normal oc-text-muted">Email</dt>
<dd>
<span data-current-language="en" data-msgid="No email has been set up">No email has been set up</span>
<span>No email has been set up</span>
</dd>
</div>
<div class="account-page-info-groups oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" data-current-language="en" data-msgid="Group memberships">Group memberships</dt>
<dt class="oc-text-normal oc-text-muted">Group memberships</dt>
<dd>
<span data-current-language="en" data-msgid="You are not part of any group">You are not part of any group</span>
<span>You are not part of any group</span>
</dd>
</div>
<!--v-if-->
<div class="account-page-logout-all-devices oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted">Logout from active devices</dt>
<dd>
<oc-button-stub appearance="raw" href="https://account-manager/logout" target="_blank" type="a"></oc-button-stub>
</dd>
</div>
</dl>
`;

Expand Down
22 changes: 22 additions & 0 deletions packages/web-runtime/tests/unit/pages/account.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ const selectors = {
groupNamesEmpty: '[data-testid="group-names-empty"]'
}

jest.mock('web-pkg/src/configuration', () => ({
configurationManager: {
logoutUrl: 'https://account-manager/logout'
}
}))

describe('account page', () => {
describe('header section', () => {
it('renders page title', () => {
Expand Down Expand Up @@ -113,6 +119,22 @@ describe('account page', () => {
expect(wrapper.vm.isChangePasswordEnabled).toBeFalsy()
})
})
describe('Logout from all devices link', () => {
it('should render the logout from active devices if logoutUrl is provided', () => {
const { wrapper } = getWrapper()
expect(wrapper.find('[data-testid="logout"]').exists()).toBe(true)
})
it("shouldn't render the logout from active devices if logoutUrl isn't provided", () => {
const { wrapper } = getWrapper()
wrapper.vm.logoutUrl = undefined
expect(wrapper.find('[data-testid="logout"]').exists()).toBe(true)
})
it('should use url from configuration manager', () => {
const { wrapper } = getWrapper()
const button = wrapper.find('oc-button-stub')
expect(button.attributes('href')).toBe('https://account-manager/logout')
})
})
})

function getWrapper({ data = {}, user = {}, capabilities = {}, accountEditLink = undefined } = {}) {
Expand Down

0 comments on commit 912563b

Please sign in to comment.