web/admin: revamped rbac and user settings tabs (#8299)
* web/admin: fix duplicate RBAC preview banner on permission modal Signed-off-by: Jens Langhammer <jens@goauthentik.io> * switch non-embedded permission page to use vertical tabs Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix some leftover html? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * move stuff into vertical subtab Signed-off-by: Jens Langhammer <jens@goauthentik.io> * show all of users permission tabs on one main tab Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rework role page to match user page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use separate tabs Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rename role permission tables to match user tables Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rename to credentials and tokens Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add country icon to session list Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add oauth access token list Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add helper to get relative time Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use pfdivider Signed-off-by: Jens Langhammer <jens@goauthentik.io> * replace plain hr with pf-c-divider Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use new logic for showing relative time in charts Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use consistent relative time for event display Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove more leftovers Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix some alignment issues on the admin dashboard Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update storybook map Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add sanity check to event app lookup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make api drawer header fixed Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix table padding for toggle Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix notification drawer for user interface Signed-off-by: Jens Langhammer <jens@goauthentik.io> * enable system task search Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix formatting, exclude generated script from formatting Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: minor fixes There's a renderer (it's not a component, not yet) for producing definition lists without the risk of missing a class or tag. Breaking conditionally rendered components out to make their use easier to identify. * fix prettier Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix outpost form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix more flaky tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * re-create locale Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add some description for different permission views Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix system task search Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update docs Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Ken Sternberg <ken@goauthentik.io>
This commit is contained in:
@ -86,7 +86,6 @@ class NotificationTransportViewSet(UsedByMixin, ModelViewSet):
|
|||||||
event = Event.new(
|
event = Event.new(
|
||||||
action="notification_test",
|
action="notification_test",
|
||||||
user=get_user(request.user),
|
user=get_user(request.user),
|
||||||
app=self.__class__.__module__,
|
|
||||||
context={"foo": "bar"},
|
context={"foo": "bar"},
|
||||||
)
|
)
|
||||||
event.save()
|
event.save()
|
||||||
|
@ -209,8 +209,9 @@ class Event(SerializerModel, ExpiringModel):
|
|||||||
app = parent.f_globals["__name__"]
|
app = parent.f_globals["__name__"]
|
||||||
# Attempt to match the calling module to the django app it belongs to
|
# Attempt to match the calling module to the django app it belongs to
|
||||||
# if we can't find a match, keep the module name
|
# if we can't find a match, keep the module name
|
||||||
django_apps = get_close_matches(app, django_app_names(), n=1)
|
django_apps: list[str] = get_close_matches(app, django_app_names(), n=1)
|
||||||
if len(django_apps) > 0:
|
# Also ensure that closest django app has the correct prefix
|
||||||
|
if len(django_apps) > 0 and django_apps[0].startswith(app):
|
||||||
app = django_apps[0]
|
app = django_apps[0]
|
||||||
cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs))
|
cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs))
|
||||||
event = Event(action=action, app=app, context=cleaned_kwargs)
|
event = Event(action=action, app=app, context=cleaned_kwargs)
|
||||||
|
@ -70,7 +70,7 @@ class TestRecovery(TenantAPITestCase):
|
|||||||
body = loads(response.content.decode())
|
body = loads(response.content.decode())
|
||||||
token = Token.objects.get(intent=TokenIntents.INTENT_RECOVERY, user=self.user)
|
token = Token.objects.get(intent=TokenIntents.INTENT_RECOVERY, user=self.user)
|
||||||
self.assertIn(token.key, body["url"])
|
self.assertIn(token.key, body["url"])
|
||||||
self.assertEqual(len(Token.objects.all()), 1)
|
self.assertEqual(len(Token.objects.filter(intent=TokenIntents.INTENT_RECOVERY)), 1)
|
||||||
|
|
||||||
@CONFIG.patch("outposts.disable_embedded_outpost", True)
|
@CONFIG.patch("outposts.disable_embedded_outpost", True)
|
||||||
@CONFIG.patch("tenants.enabled", True)
|
@CONFIG.patch("tenants.enabled", True)
|
||||||
@ -86,4 +86,4 @@ class TestRecovery(TenantAPITestCase):
|
|||||||
headers=HEADERS,
|
headers=HEADERS,
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 404)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(len(Token.objects.all()), 0)
|
self.assertEqual(len(Token.objects.filter(intent=TokenIntents.INTENT_RECOVERY)), 0)
|
||||||
|
@ -11,3 +11,4 @@ src/locales/
|
|||||||
storybook-static/
|
storybook-static/
|
||||||
# Prettier breaks the tsconfig file
|
# Prettier breaks the tsconfig file
|
||||||
tsconfig.json
|
tsconfig.json
|
||||||
|
.storybook/css-import-maps*
|
||||||
|
@ -27,6 +27,7 @@ const rawCssImportMaps = [
|
|||||||
'import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";',
|
'import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";',
|
||||||
'import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";',
|
'import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";',
|
||||||
'import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";',
|
'import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";',
|
||||||
|
'import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";',
|
||||||
'import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";',
|
'import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";',
|
||||||
'import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";',
|
'import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";',
|
||||||
'import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";',
|
'import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";',
|
||||||
@ -70,10 +71,8 @@ const rawCssImportMaps = [
|
|||||||
'import styles from "./LibraryPageImpl.css";',
|
'import styles from "./LibraryPageImpl.css";',
|
||||||
];
|
];
|
||||||
|
|
||||||
const cssImportMaps = rawCssImportMaps.reduce(
|
const cssImportMaps = rawCssImportMaps.reduce((acc, line) => (
|
||||||
(acc, line) => ({ ...acc, [line]: line.replace(/\.css/, ".css?inline") }),
|
{...acc, [line]: line.replace(/\.css/, ".css?inline")}), {});
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
export { cssImportMaps };
|
export { cssImportMaps };
|
||||||
export default cssImportMaps;
|
export default cssImportMaps;
|
||||||
|
@ -63,8 +63,7 @@ function getTheImportLines(importPaths: string[]) {
|
|||||||
const importPaths = getTheSourceFiles();
|
const importPaths = getTheSourceFiles();
|
||||||
const importLines = getTheImportLines(importPaths);
|
const importLines = getTheImportLines(importPaths);
|
||||||
|
|
||||||
const outputFile = `
|
const outputFile = `// THIS IS A GENERATED FILE. DO NOT EDIT BY HAND.
|
||||||
// THIS IS A GENERATED FILE. DO NOT EDIT BY HAND.
|
|
||||||
//
|
//
|
||||||
// This file is generated by the build-storybook-import-maps script in the UI's base directory.
|
// This file is generated by the build-storybook-import-maps script in the UI's base directory.
|
||||||
// This is a *hack* to work around an inconsistency in the way rollup, vite, and storybook
|
// This is a *hack* to work around an inconsistency in the way rollup, vite, and storybook
|
||||||
|
@ -19,6 +19,7 @@ import { CSSResult, TemplateResult, css, html } from "lit";
|
|||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||||
|
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
|
||||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||||
@ -41,15 +42,12 @@ export class AdminOverviewPage extends AKElement {
|
|||||||
PFPage,
|
PFPage,
|
||||||
PFContent,
|
PFContent,
|
||||||
PFList,
|
PFList,
|
||||||
|
PFDivider,
|
||||||
css`
|
css`
|
||||||
.row-divider {
|
.pf-l-grid__item {
|
||||||
margin-top: -4px;
|
height: 100%;
|
||||||
margin-bottom: -4px;
|
|
||||||
}
|
}
|
||||||
.graph-container {
|
.pf-l-grid__item.big-graph-container {
|
||||||
height: 20em;
|
|
||||||
}
|
|
||||||
.big-graph-container {
|
|
||||||
height: 35em;
|
height: 35em;
|
||||||
}
|
}
|
||||||
.card-container {
|
.card-container {
|
||||||
@ -82,9 +80,7 @@ export class AdminOverviewPage extends AKElement {
|
|||||||
<div class="pf-l-grid pf-m-gutter">
|
<div class="pf-l-grid pf-m-gutter">
|
||||||
<!-- row 1 -->
|
<!-- row 1 -->
|
||||||
<div class="pf-l-grid__item pf-m-6-col pf-l-grid pf-m-gutter">
|
<div class="pf-l-grid__item pf-m-6-col pf-l-grid pf-m-gutter">
|
||||||
<div
|
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl">
|
||||||
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl graph-container"
|
|
||||||
>
|
|
||||||
<ak-aggregate-card
|
<ak-aggregate-card
|
||||||
icon="fa fa-share"
|
icon="fa fa-share"
|
||||||
header=${msg("Quick actions")}
|
header=${msg("Quick actions")}
|
||||||
@ -136,9 +132,7 @@ export class AdminOverviewPage extends AKElement {
|
|||||||
</ul>
|
</ul>
|
||||||
</ak-aggregate-card>
|
</ak-aggregate-card>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl">
|
||||||
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl graph-container"
|
|
||||||
>
|
|
||||||
<ak-aggregate-card
|
<ak-aggregate-card
|
||||||
icon="pf-icon pf-icon-zone"
|
icon="pf-icon pf-icon-zone"
|
||||||
header=${msg("Outpost status")}
|
header=${msg("Outpost status")}
|
||||||
@ -148,14 +142,14 @@ export class AdminOverviewPage extends AKElement {
|
|||||||
</ak-aggregate-card>
|
</ak-aggregate-card>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-4-col-on-2xl graph-container"
|
class="pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-4-col-on-2xl"
|
||||||
>
|
>
|
||||||
<ak-aggregate-card icon="fa fa-sync-alt" header=${msg("Sync status")}>
|
<ak-aggregate-card icon="fa fa-sync-alt" header=${msg("Sync status")}>
|
||||||
<ak-admin-status-chart-sync></ak-admin-status-chart-sync>
|
<ak-admin-status-chart-sync></ak-admin-status-chart-sync>
|
||||||
</ak-aggregate-card>
|
</ak-aggregate-card>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-l-grid__item pf-m-12-col row-divider">
|
<div class="pf-l-grid__item pf-m-12-col">
|
||||||
<hr />
|
<hr class="pf-c-divider" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="pf-l-grid__item pf-m-6-col pf-m-4-col-on-md pf-m-4-col-on-xl card-container"
|
class="pf-l-grid__item pf-m-6-col pf-m-4-col-on-md pf-m-4-col-on-xl card-container"
|
||||||
@ -176,8 +170,8 @@ export class AdminOverviewPage extends AKElement {
|
|||||||
<div class="pf-l-grid__item pf-m-6-col">
|
<div class="pf-l-grid__item pf-m-6-col">
|
||||||
<ak-recent-events pageSize="6"></ak-recent-events>
|
<ak-recent-events pageSize="6"></ak-recent-events>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-l-grid__item pf-m-12-col row-divider">
|
<div class="pf-l-grid__item pf-m-12-col">
|
||||||
<hr />
|
<hr class="pf-c-divider" />
|
||||||
</div>
|
</div>
|
||||||
<!-- row 3 -->
|
<!-- row 3 -->
|
||||||
<div
|
<div
|
||||||
|
@ -8,6 +8,7 @@ import { CSSResult, TemplateResult, css, html } from "lit";
|
|||||||
import { customElement } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||||
|
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
|
||||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||||
@ -22,14 +23,8 @@ export class DashboardUserPage extends AKElement {
|
|||||||
PFPage,
|
PFPage,
|
||||||
PFContent,
|
PFContent,
|
||||||
PFList,
|
PFList,
|
||||||
|
PFDivider,
|
||||||
css`
|
css`
|
||||||
.row-divider {
|
|
||||||
margin-top: -4px;
|
|
||||||
margin-bottom: -4px;
|
|
||||||
}
|
|
||||||
.graph-container {
|
|
||||||
height: 20em;
|
|
||||||
}
|
|
||||||
.big-graph-container {
|
.big-graph-container {
|
||||||
height: 35em;
|
height: 35em;
|
||||||
}
|
}
|
||||||
@ -59,8 +54,8 @@ export class DashboardUserPage extends AKElement {
|
|||||||
</ak-charts-admin-model-per-day>
|
</ak-charts-admin-model-per-day>
|
||||||
</ak-aggregate-card>
|
</ak-aggregate-card>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-l-grid__item pf-m-12-col row-divider">
|
<div class="pf-l-grid__item pf-m-12-col">
|
||||||
<hr />
|
<hr class="pf-c-divider" />
|
||||||
</div>
|
</div>
|
||||||
<!-- row 2 -->
|
<!-- row 2 -->
|
||||||
<div
|
<div
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
@ -71,7 +72,8 @@ export class RecentEventsCard extends Table<Event> {
|
|||||||
html`<div><a href="${`#/events/log/${item.pk}`}">${actionToLabel(item.action)}</a></div>
|
html`<div><a href="${`#/events/log/${item.pk}`}">${actionToLabel(item.action)}</a></div>
|
||||||
<small>${item.app}</small>`,
|
<small>${item.app}</small>`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<span>${item.created?.toLocaleString()}</span>`,
|
html`<div>${getRelativeTime(item.created)}</div>
|
||||||
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html` <div>${item.clientIp || msg("-")}</div>
|
html` <div>${item.clientIp || msg("-")}</div>
|
||||||
<small>${EventGeo(item)}</small>`,
|
<small>${EventGeo(item)}</small>`,
|
||||||
html`<span>${item.brand?.name || msg("-")}</span>`,
|
html`<span>${item.brand?.name || msg("-")}</span>`,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { AKChart, RGBAColor } from "@goauthentik/elements/charts/Chart";
|
import { AKChart, RGBAColor } from "@goauthentik/elements/charts/Chart";
|
||||||
import { ChartData, Tick } from "chart.js";
|
import { ChartData } from "chart.js";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { customElement } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
|
|
||||||
import { AdminApi, LoginMetrics } from "@goauthentik/api";
|
import { AdminApi, LoginMetrics } from "@goauthentik/api";
|
||||||
@ -13,13 +13,6 @@ export class AdminLoginAuthorizeChart extends AKChart<LoginMetrics> {
|
|||||||
return new AdminApi(DEFAULT_CONFIG).adminMetricsRetrieve();
|
return new AdminApi(DEFAULT_CONFIG).adminMetricsRetrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
|
||||||
const valueStamp = ticks[index];
|
|
||||||
const delta = Date.now() - valueStamp.value;
|
|
||||||
const ago = Math.round(delta / 1000 / 3600 / 24);
|
|
||||||
return msg(str`${ago} day(s) ago`);
|
|
||||||
}
|
|
||||||
|
|
||||||
getChartData(data: LoginMetrics): ChartData {
|
getChartData(data: LoginMetrics): ChartData {
|
||||||
return {
|
return {
|
||||||
datasets: [
|
datasets: [
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import "@goauthentik/admin/events/EventVolumeChart";
|
import "@goauthentik/admin/events/EventVolumeChart";
|
||||||
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
@ -82,9 +83,9 @@ export class EventListPage extends TablePage<Event> {
|
|||||||
html`<div>${actionToLabel(item.action)}</div>
|
html`<div>${actionToLabel(item.action)}</div>
|
||||||
<small>${item.app}</small>`,
|
<small>${item.app}</small>`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<span>${item.created?.toLocaleString()}</span>`,
|
html`<div>${getRelativeTime(item.created)}</div>
|
||||||
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<div>${item.clientIp || msg("-")}</div>
|
html`<div>${item.clientIp || msg("-")}</div>
|
||||||
|
|
||||||
<small>${EventGeo(item)}</small>`,
|
<small>${EventGeo(item)}</small>`,
|
||||||
html`<span>${item.brand?.name || msg("-")}</span>`,
|
html`<span>${item.brand?.name || msg("-")}</span>`,
|
||||||
html`<a href="#/events/log/${item.pk}">
|
html`<a href="#/events/log/${item.pk}">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
@ -99,7 +100,8 @@ export class EventViewPage extends AKElement {
|
|||||||
</dt>
|
</dt>
|
||||||
<dd class="pf-c-description-list__description">
|
<dd class="pf-c-description-list__description">
|
||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text">
|
||||||
${this.event.created?.toLocaleString()}
|
<div>${getRelativeTime(this.event.created)}</div>
|
||||||
|
<small>${this.event.created.toLocaleString()}</small>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
@ -230,25 +230,29 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
|||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-group aria-label="Advanced settings">
|
<ak-form-group aria-label="Advanced settings">
|
||||||
<span slot="header"> ${msg("Advanced settings")} </span>
|
<span slot="header"> ${msg("Advanced settings")} </span>
|
||||||
<ak-form-element-horizontal label=${msg("Configuration")} name="config">
|
<div slot="body" class="pf-c-form">
|
||||||
<ak-codemirror
|
<ak-form-element-horizontal label=${msg("Configuration")} name="config">
|
||||||
mode=${CodeMirrorMode.YAML}
|
<ak-codemirror
|
||||||
value="${YAML.stringify(
|
mode=${CodeMirrorMode.YAML}
|
||||||
this.instance ? this.instance.config : this.defaultConfig?.config,
|
value="${YAML.stringify(
|
||||||
)}"
|
this.instance ? this.instance.config : this.defaultConfig?.config,
|
||||||
></ak-codemirror>
|
)}"
|
||||||
<p class="pf-c-form__helper-text">
|
></ak-codemirror>
|
||||||
${msg("Set custom attributes using YAML or JSON.")}
|
<p class="pf-c-form__helper-text">
|
||||||
</p>
|
${msg("Set custom attributes using YAML or JSON.")}
|
||||||
<p class="pf-c-form__helper-text">
|
</p>
|
||||||
${msg("See more here:")}
|
<p class="pf-c-form__helper-text">
|
||||||
<a
|
${msg("See more here:")}
|
||||||
target="_blank"
|
<a
|
||||||
href="${docLink("/docs/outposts?utm_source=authentik#configuration")}"
|
target="_blank"
|
||||||
>${msg("Documentation")}</a
|
href="${docLink(
|
||||||
>
|
"/docs/outposts?utm_source=authentik#configuration",
|
||||||
</p>
|
)}"
|
||||||
</ak-form-element-horizontal>
|
>${msg("Documentation")}</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
|
</div>
|
||||||
</ak-form-group>`;
|
</ak-form-group>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
|||||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||||
|
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
|
||||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
@ -70,6 +71,7 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
PFForm,
|
PFForm,
|
||||||
PFFormControl,
|
PFFormControl,
|
||||||
PFBanner,
|
PFBanner,
|
||||||
|
PFDivider,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +260,7 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
value="${this.providerUrls?.issuer || msg("-")}"
|
value="${this.providerUrls?.issuer || msg("-")}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr class="pf-c-divider" />
|
||||||
<div class="pf-c-form__group">
|
<div class="pf-c-form__group">
|
||||||
<label class="pf-c-form__label">
|
<label class="pf-c-form__label">
|
||||||
<span class="pf-c-form__label-text"
|
<span class="pf-c-form__label-text"
|
||||||
|
@ -11,8 +11,8 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
|||||||
|
|
||||||
import { Permission, RbacApi } from "@goauthentik/api";
|
import { Permission, RbacApi } from "@goauthentik/api";
|
||||||
|
|
||||||
@customElement("ak-role-permissions-global-table")
|
@customElement("ak-role-assigned-global-permissions-table")
|
||||||
export class RolePermissionGlobalTable extends Table<Permission> {
|
export class RoleAssignedGlobalPermissionsTable extends Table<Permission> {
|
||||||
@property()
|
@property()
|
||||||
roleUuid?: string;
|
roleUuid?: string;
|
||||||
|
|
@ -10,8 +10,8 @@ import { customElement, property } from "lit/decorators.js";
|
|||||||
|
|
||||||
import { ExtraRoleObjectPermission, ModelEnum, RbacApi } from "@goauthentik/api";
|
import { ExtraRoleObjectPermission, ModelEnum, RbacApi } from "@goauthentik/api";
|
||||||
|
|
||||||
@customElement("ak-role-permissions-object-table")
|
@customElement("ak-role-assigned-object-permissions-table")
|
||||||
export class RolePermissionObjectTable extends Table<ExtraRoleObjectPermission> {
|
export class RoleAssignedObjectPermissionTable extends Table<ExtraRoleObjectPermission> {
|
||||||
@property()
|
@property()
|
||||||
roleUuid?: string;
|
roleUuid?: string;
|
||||||
|
|
@ -1,21 +1,20 @@
|
|||||||
import "@goauthentik/admin/groups/RelatedGroupList";
|
import "@goauthentik/admin/groups/RelatedGroupList";
|
||||||
import "@goauthentik/app/admin/roles/RolePermissionGlobalTable";
|
import "@goauthentik/admin/roles/RoleForm";
|
||||||
import "@goauthentik/app/admin/roles/RolePermissionObjectTable";
|
|
||||||
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
|
import { renderDescriptionList } from "@goauthentik/components/DescriptionList";
|
||||||
import "@goauthentik/components/events/ObjectChangelog";
|
import "@goauthentik/components/events/ObjectChangelog";
|
||||||
import "@goauthentik/components/events/UserEvents";
|
import "@goauthentik/components/events/UserEvents";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
|
||||||
import "@goauthentik/elements/PageHeader";
|
import "@goauthentik/elements/PageHeader";
|
||||||
import "@goauthentik/elements/Tabs";
|
import "@goauthentik/elements/Tabs";
|
||||||
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
import { css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
|
||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||||
@ -43,7 +42,7 @@ export class RoleViewPage extends AKElement {
|
|||||||
@state()
|
@state()
|
||||||
_role?: Role;
|
_role?: Role;
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles() {
|
||||||
return [
|
return [
|
||||||
PFBase,
|
PFBase,
|
||||||
PFPage,
|
PFPage,
|
||||||
@ -53,7 +52,6 @@ export class RoleViewPage extends AKElement {
|
|||||||
PFContent,
|
PFContent,
|
||||||
PFCard,
|
PFCard,
|
||||||
PFDescriptionList,
|
PFDescriptionList,
|
||||||
PFBanner,
|
|
||||||
css`
|
css`
|
||||||
.pf-c-description-list__description ak-action-button {
|
.pf-c-description-list__description ak-action-button {
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
@ -74,7 +72,7 @@ export class RoleViewPage extends AKElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render() {
|
||||||
return html`<ak-page-header
|
return html`<ak-page-header
|
||||||
icon="fa fa-lock"
|
icon="fa fa-lock"
|
||||||
header=${msg(str`Role ${this._role?.name || ""}`)}
|
header=${msg(str`Role ${this._role?.name || ""}`)}
|
||||||
@ -83,73 +81,61 @@ export class RoleViewPage extends AKElement {
|
|||||||
${this.renderBody()}`;
|
${this.renderBody()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBody(): TemplateResult {
|
renderUpdateControl(role: Role) {
|
||||||
|
return html` <div class="pf-c-description-list__text">
|
||||||
|
<ak-forms-modal>
|
||||||
|
<span slot="submit"> ${msg("Update")} </span>
|
||||||
|
<span slot="header"> ${msg("Update Role")} </span>
|
||||||
|
<ak-role-form slot="form" .instancePk=${role.pk}> </ak-role-form>
|
||||||
|
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Edit")}</button>
|
||||||
|
</ak-forms-modal>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBody() {
|
||||||
if (!this._role) {
|
if (!this._role) {
|
||||||
return html``;
|
return nothing;
|
||||||
}
|
}
|
||||||
return html`<div class="pf-c-banner pf-m-info">
|
|
||||||
${msg("RBAC is in preview.")}
|
return html` <ak-tabs>
|
||||||
<a href="mailto:hello@goauthentik.io">${msg("Send us feedback!")}</a>
|
<section
|
||||||
</div>
|
slot="page-overview"
|
||||||
<ak-tabs>
|
data-tab-title="${msg("Overview")}"
|
||||||
<section
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
slot="page-overview"
|
>
|
||||||
data-tab-title="${msg("Overview")}"
|
<div class="pf-l-grid pf-m-gutter">
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
<div
|
||||||
>
|
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-3-col-on-xl pf-m-3-col-on-2xl"
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
>
|
||||||
<div
|
<div class="pf-c-card__title">${msg("Role Info")}</div>
|
||||||
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-3-col-on-xl pf-m-3-col-on-2xl"
|
<div class="pf-c-card__body">
|
||||||
>
|
${renderDescriptionList([
|
||||||
<div class="pf-c-card__title">${msg("Role Info")}</div>
|
[msg("Name"), this._role.name],
|
||||||
<div class="pf-c-card__body">
|
[msg("Edit"), this.renderUpdateControl(this._role)],
|
||||||
<dl class="pf-c-description-list">
|
])}
|
||||||
<div class="pf-c-description-list__group">
|
|
||||||
<dt class="pf-c-description-list__term">
|
|
||||||
<span class="pf-c-description-list__text"
|
|
||||||
>${msg("Name")}</span
|
|
||||||
>
|
|
||||||
</dt>
|
|
||||||
<dd class="pf-c-description-list__description">
|
|
||||||
<div class="pf-c-description-list__text">
|
|
||||||
${this._role.name}
|
|
||||||
</div>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-9-col-on-xl pf-m-9-col-on-2xl"
|
|
||||||
>
|
|
||||||
<div class="pf-c-card__title">
|
|
||||||
${msg("Assigned global permissions")}
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-role-permissions-global-table
|
|
||||||
roleUuid=${this._role.pk}
|
|
||||||
></ak-role-permissions-global-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
|
||||||
<div class="pf-c-card__title">
|
|
||||||
${msg("Assigned object permissions")}
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-role-permissions-object-table
|
|
||||||
roleUuid=${this._role.pk}
|
|
||||||
></ak-role-permissions-object-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<div
|
||||||
<ak-rbac-object-permission-page
|
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-9-col-on-xl pf-m-9-col-on-2xl"
|
||||||
slot="page-permissions"
|
>
|
||||||
data-tab-title="${msg("Permissions")}"
|
<div class="pf-c-card__title">${msg("Changelog")}</div>
|
||||||
model=${RbacPermissionsAssignedByUsersListModelEnum.RbacRole}
|
<div class="pf-c-card__body">
|
||||||
objectPk=${this._role.pk}
|
<ak-object-changelog
|
||||||
.showBanner=${false}
|
targetModelPk=${this.roleId}
|
||||||
></ak-rbac-object-permission-page>
|
targetModelApp="authentik_rbac"
|
||||||
</ak-tabs>`;
|
targetModelName="role"
|
||||||
|
>
|
||||||
|
</ak-object-changelog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<ak-rbac-object-permission-page
|
||||||
|
slot="page-permissions"
|
||||||
|
data-tab-title="${msg("Permissions")}"
|
||||||
|
model=${RbacPermissionsAssignedByUsersListModelEnum.RbacRole}
|
||||||
|
objectPk=${this._role.pk}
|
||||||
|
></ak-rbac-object-permission-page>
|
||||||
|
</ak-tabs>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@ export class SystemTaskListPage extends TablePage<SystemTask> {
|
|||||||
|
|
||||||
expandable = true;
|
expandable = true;
|
||||||
|
|
||||||
|
searchEnabled(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
order = "name";
|
order = "name";
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@ import "@goauthentik/admin/users/UserActiveForm";
|
|||||||
import "@goauthentik/admin/users/UserChart";
|
import "@goauthentik/admin/users/UserChart";
|
||||||
import "@goauthentik/admin/users/UserForm";
|
import "@goauthentik/admin/users/UserForm";
|
||||||
import "@goauthentik/admin/users/UserPasswordForm";
|
import "@goauthentik/admin/users/UserPasswordForm";
|
||||||
import "@goauthentik/app/admin/users/UserAssignedGlobalPermissionsTable";
|
|
||||||
import "@goauthentik/app/admin/users/UserAssignedObjectPermissionsTable";
|
|
||||||
import {
|
import {
|
||||||
renderRecoveryEmailRequest,
|
renderRecoveryEmailRequest,
|
||||||
requestRecoveryLink,
|
requestRecoveryLink,
|
||||||
} from "@goauthentik/app/admin/users/UserListPage";
|
} from "@goauthentik/app/admin/users/UserListPage";
|
||||||
import { me } from "@goauthentik/app/common/users";
|
import { me } from "@goauthentik/app/common/users";
|
||||||
|
import "@goauthentik/app/elements/oauth/UserAccessTokenList";
|
||||||
|
import "@goauthentik/app/elements/oauth/UserRefreshTokenList";
|
||||||
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
@ -31,12 +31,11 @@ import "@goauthentik/elements/Tabs";
|
|||||||
import "@goauthentik/elements/buttons/ActionButton";
|
import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
import "@goauthentik/elements/forms/ModalForm";
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
import "@goauthentik/elements/oauth/UserRefreshList";
|
|
||||||
import "@goauthentik/elements/user/SessionList";
|
import "@goauthentik/elements/user/SessionList";
|
||||||
import "@goauthentik/elements/user/UserConsentList";
|
import "@goauthentik/elements/user/UserConsentList";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { css, html, nothing } from "lit";
|
import { TemplateResult, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
||||||
@ -227,45 +226,94 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) {
|
|||||||
|
|
||||||
renderRecoveryButtons(user: User) {
|
renderRecoveryButtons(user: User) {
|
||||||
return html`<div class="ak-button-collection">
|
return html`<div class="ak-button-collection">
|
||||||
<ak-forms-modal size=${PFSize.Medium} id="update-password-request">
|
<ak-forms-modal size=${PFSize.Medium} id="update-password-request">
|
||||||
<span slot="submit">${msg("Update password")}</span>
|
<span slot="submit">${msg("Update password")}</span>
|
||||||
<span slot="header">${msg("Update password")}</span>
|
<span slot="header">${msg("Update password")}</span>
|
||||||
<ak-user-password-form
|
<ak-user-password-form slot="form" .instancePk=${user.pk}></ak-user-password-form>
|
||||||
slot="form"
|
<button slot="trigger" class="pf-c-button pf-m-secondary pf-m-block">
|
||||||
.instancePk=${user.pk}
|
<pf-tooltip position="top" content=${msg("Enter a new password for this user")}>
|
||||||
></ak-user-password-form>
|
${msg("Set password")}
|
||||||
<button
|
</pf-tooltip>
|
||||||
slot="trigger"
|
</button>
|
||||||
class="pf-c-button pf-m-secondary pf-m-block"
|
</ak-forms-modal>
|
||||||
>
|
<ak-action-button
|
||||||
<pf-tooltip
|
id="reset-password-button"
|
||||||
position="top"
|
class="pf-m-secondary pf-m-block"
|
||||||
content=${msg("Enter a new password for this user")}
|
.apiRequest=${() => requestRecoveryLink(user)}
|
||||||
>
|
>
|
||||||
${msg("Set password")}
|
<pf-tooltip
|
||||||
</pf-tooltip>
|
position="top"
|
||||||
</button>
|
content=${msg("Create a link for this user to reset their password")}
|
||||||
</ak-forms-modal>
|
>
|
||||||
<ak-action-button
|
${msg("Create Recovery Link")}
|
||||||
id="reset-password-button"
|
</pf-tooltip>
|
||||||
class="pf-m-secondary pf-m-block"
|
</ak-action-button>
|
||||||
.apiRequest=${() => requestRecoveryLink(user)}
|
${user.email ? renderRecoveryEmailRequest(user) : nothing}
|
||||||
>
|
</div> `;
|
||||||
<pf-tooltip
|
}
|
||||||
position="top"
|
|
||||||
content=${msg(
|
renderTabCredentialsToken(user: User): TemplateResult {
|
||||||
"Create a link for this user to reset their password",
|
return html`
|
||||||
)}
|
<ak-tabs pageIdentifier="userCredentialsTokens" ?vertical=${true}>
|
||||||
>
|
<section
|
||||||
${msg("Create Recovery Link")}
|
slot="page-sessions"
|
||||||
</pf-tooltip>
|
data-tab-title="${msg("Sessions")}"
|
||||||
</ak-action-button>
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
${user.email ? renderRecoveryEmailRequest(user) : nothing}
|
>
|
||||||
</div>
|
<div class="pf-c-card">
|
||||||
</dd>
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-session-list targetUser=${user.username}>
|
||||||
|
</ak-user-session-list>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</section>
|
||||||
</div>
|
<section
|
||||||
|
slot="page-consent"
|
||||||
|
data-tab-title="${msg("Explicit Consent")}"
|
||||||
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
|
>
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-consent-list userId=${user.pk}> </ak-user-consent-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section
|
||||||
|
slot="page-oauth-access"
|
||||||
|
data-tab-title="${msg("OAuth Access Tokens")}"
|
||||||
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
|
>
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-oauth-access-token-list userId=${user.pk}>
|
||||||
|
</ak-user-oauth-access-token-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section
|
||||||
|
slot="page-oauth-refresh"
|
||||||
|
data-tab-title="${msg("OAuth Refresh Tokens")}"
|
||||||
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
|
>
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-oauth-refresh-token-list userId=${user.pk}>
|
||||||
|
</ak-user-oauth-refresh-token-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section
|
||||||
|
slot="page-mfa-authenticators"
|
||||||
|
data-tab-title="${msg("MFA Authenticators")}"
|
||||||
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
|
>
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-device-table userId=${user.pk}> </ak-user-device-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ak-tabs>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,18 +374,6 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section
|
|
||||||
slot="page-sessions"
|
|
||||||
data-tab-title="${msg("Sessions")}"
|
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
|
||||||
>
|
|
||||||
<div class="pf-c-card">
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-session-list targetUser=${this.user.username}>
|
|
||||||
</ak-user-session-list>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section
|
<section
|
||||||
slot="page-groups"
|
slot="page-groups"
|
||||||
data-tab-title="${msg("Groups")}"
|
data-tab-title="${msg("Groups")}"
|
||||||
@ -360,78 +396,16 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section
|
<section slot="page-credentials" data-tab-title="${msg("Credentials / Tokens")}">
|
||||||
slot="page-consent"
|
${this.renderTabCredentialsToken(this.user)}
|
||||||
data-tab-title="${msg("Explicit Consent")}"
|
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
|
||||||
>
|
|
||||||
<div class="pf-c-card">
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-consent-list userId=${this.user.pk}> </ak-user-consent-list>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section
|
|
||||||
slot="page-oauth-refresh"
|
|
||||||
data-tab-title="${msg("OAuth Refresh Tokens")}"
|
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
|
||||||
>
|
|
||||||
<div class="pf-c-card">
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-oauth-refresh-list userId=${this.user.pk}>
|
|
||||||
</ak-user-oauth-refresh-list>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section
|
|
||||||
slot="page-mfa-authenticators"
|
|
||||||
data-tab-title="${msg("MFA Authenticators")}"
|
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
|
||||||
>
|
|
||||||
<div class="pf-c-card">
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-device-table userId=${this.user.pk}> </ak-user-device-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
<ak-rbac-object-permission-page
|
<ak-rbac-object-permission-page
|
||||||
slot="page-permissions"
|
slot="page-permissions"
|
||||||
data-tab-title="${msg("Permissions")}"
|
data-tab-title="${msg("Permissions")}"
|
||||||
model=${RbacPermissionsAssignedByUsersListModelEnum.CoreUser}
|
model=${RbacPermissionsAssignedByUsersListModelEnum.CoreUser}
|
||||||
objectPk=${this.user.pk}
|
objectPk=${this.user.pk}
|
||||||
></ak-rbac-object-permission-page>
|
|
||||||
<div
|
|
||||||
slot="page-mfa-assigned-permissions"
|
|
||||||
data-tab-title="${msg("Assigned permissions")}"
|
|
||||||
class=""
|
|
||||||
>
|
>
|
||||||
<div class="pf-c-banner pf-m-info">
|
</ak-rbac-object-permission-page>
|
||||||
${msg("RBAC is in preview.")}
|
|
||||||
<a href="mailto:hello@goauthentik.io">${msg("Send us feedback!")}</a>
|
|
||||||
</div>
|
|
||||||
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
|
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
|
||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
|
||||||
<div class="pf-c-card__title">
|
|
||||||
${msg("Assigned global permissions")}
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-assigned-global-permissions-table userId=${this.user.pk}>
|
|
||||||
</ak-user-assigned-global-permissions-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
|
||||||
<div class="pf-c-card__title">
|
|
||||||
${msg("Assigned object permissions")}
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-card__body">
|
|
||||||
<ak-user-assigned-object-permissions-table userId=${this.user.pk}>
|
|
||||||
</ak-user-assigned-object-permissions-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</ak-tabs>`;
|
</ak-tabs>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,3 +149,25 @@ export function adaptCSS(sheet: AdaptableStylesheet[]): CSSStyleSheet[];
|
|||||||
export function adaptCSS(sheet: AdaptableStylesheet | AdaptableStylesheet[]): AdaptedStylesheets {
|
export function adaptCSS(sheet: AdaptableStylesheet | AdaptableStylesheet[]): AdaptedStylesheets {
|
||||||
return Array.isArray(sheet) ? sheet.map(_adaptCSS) : _adaptCSS(sheet);
|
return Array.isArray(sheet) ? sheet.map(_adaptCSS) : _adaptCSS(sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _timeUnits = new Map<Intl.RelativeTimeFormatUnit, number>([
|
||||||
|
["year", 24 * 60 * 60 * 1000 * 365],
|
||||||
|
["month", (24 * 60 * 60 * 1000 * 365) / 12],
|
||||||
|
["day", 24 * 60 * 60 * 1000],
|
||||||
|
["hour", 60 * 60 * 1000],
|
||||||
|
["minute", 60 * 1000],
|
||||||
|
["second", 1000],
|
||||||
|
]);
|
||||||
|
|
||||||
|
export function getRelativeTime(d1: Date, d2: Date = new Date()): string {
|
||||||
|
const rtf = new Intl.RelativeTimeFormat("default", { numeric: "auto" });
|
||||||
|
const elapsed = d1.getTime() - d2.getTime();
|
||||||
|
|
||||||
|
// "Math.abs" accounts for both "past" & "future" scenarios
|
||||||
|
for (const [key, value] of _timeUnits) {
|
||||||
|
if (Math.abs(elapsed) > value || key == "second") {
|
||||||
|
return rtf.format(Math.round(elapsed / value), key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtf.format(Math.round(elapsed / 1000), "second");
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { EventGeo, EventUser } from "@goauthentik/app/admin/events/utils";
|
import { EventGeo, EventUser } from "@goauthentik/app/admin/events/utils";
|
||||||
import { actionToLabel } from "@goauthentik/app/common/labels";
|
import { actionToLabel } from "@goauthentik/app/common/labels";
|
||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||||
@ -46,7 +47,7 @@ export class ObjectChangelog extends Table<Event> {
|
|||||||
let modelName = this._targetModelName;
|
let modelName = this._targetModelName;
|
||||||
let appName = this.targetModelApp;
|
let appName = this.targetModelApp;
|
||||||
if (this._targetModelName.indexOf(".") !== -1) {
|
if (this._targetModelName.indexOf(".") !== -1) {
|
||||||
const parts = this._targetModelName.split(".");
|
const parts = this._targetModelName.split(".", 1);
|
||||||
appName = parts[0];
|
appName = parts[0];
|
||||||
modelName = parts[1];
|
modelName = parts[1];
|
||||||
}
|
}
|
||||||
@ -77,7 +78,8 @@ export class ObjectChangelog extends Table<Event> {
|
|||||||
return [
|
return [
|
||||||
html`${actionToLabel(item.action)}`,
|
html`${actionToLabel(item.action)}`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<span>${item.created?.toLocaleString()}</span>`,
|
html`<div>${getRelativeTime(item.created)}</div>
|
||||||
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<div>${item.clientIp || msg("-")}</div>
|
html`<div>${item.clientIp || msg("-")}</div>
|
||||||
|
|
||||||
<small>${EventGeo(item)}</small>`,
|
<small>${EventGeo(item)}</small>`,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { EventUser } from "@goauthentik/app/admin/events/utils";
|
import { EventUser } from "@goauthentik/app/admin/events/utils";
|
||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
@ -48,7 +49,8 @@ export class UserEvents extends Table<Event> {
|
|||||||
return [
|
return [
|
||||||
html`${actionToLabel(item.action)}`,
|
html`${actionToLabel(item.action)}`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<span>${item.created?.toLocaleString()}</span>`,
|
html`<div>${getRelativeTime(item.created)}</div>
|
||||||
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<span>${item.clientIp || msg("-")}</span>`,
|
html`<span>${item.clientIp || msg("-")}</span>`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ export class AggregateCard extends AKElement {
|
|||||||
${this.renderInner()}
|
${this.renderInner()}
|
||||||
${this.subtext ? html`<p class="subtext">${this.subtext}</p>` : html``}
|
${this.subtext ? html`<p class="subtext">${this.subtext}</p>` : html``}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pf-c-card__footer"> </div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { EVENT_REFRESH, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
@ -18,7 +19,7 @@ import { ArcElement, BarElement } from "chart.js";
|
|||||||
import { LinearScale, TimeScale } from "chart.js";
|
import { LinearScale, TimeScale } from "chart.js";
|
||||||
import "chartjs-adapter-moment";
|
import "chartjs-adapter-moment";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||||
import { property, state } from "lit/decorators.js";
|
import { property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
@ -161,9 +162,7 @@ export abstract class AKChart<T> extends AKElement {
|
|||||||
|
|
||||||
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
||||||
const valueStamp = ticks[index];
|
const valueStamp = ticks[index];
|
||||||
const delta = Date.now() - valueStamp.value;
|
return getRelativeTime(new Date(valueStamp.value));
|
||||||
const ago = Math.round(delta / 1000 / 3600);
|
|
||||||
return msg(str`${ago} hour(s) ago`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptions(): ChartOptions {
|
getOptions(): ChartOptions {
|
||||||
|
@ -25,8 +25,11 @@ export class APIDrawer extends AKElement {
|
|||||||
PFContent,
|
PFContent,
|
||||||
PFDropdown,
|
PFDropdown,
|
||||||
css`
|
css`
|
||||||
|
:host {
|
||||||
|
--header-height: 114px;
|
||||||
|
}
|
||||||
.pf-c-notification-drawer__header {
|
.pf-c-notification-drawer__header {
|
||||||
height: 114px;
|
height: var(--header-height);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.pf-c-notification-drawer__header-action,
|
.pf-c-notification-drawer__header-action,
|
||||||
@ -41,6 +44,9 @@ export class APIDrawer extends AKElement {
|
|||||||
.pf-c-notification-drawer__body {
|
.pf-c-notification-drawer__body {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
.pf-c-notification-drawer__list {
|
||||||
|
max-height: calc(100vh - var(--header-height));
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
93
web/src/elements/oauth/UserAccessTokenList.ts
Normal file
93
web/src/elements/oauth/UserAccessTokenList.ts
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||||
|
import "@goauthentik/components/ak-status-label";
|
||||||
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
|
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
|
|
||||||
|
import { msg } from "@lit/localize";
|
||||||
|
import { CSSResult, TemplateResult, html } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators.js";
|
||||||
|
|
||||||
|
import PFFlex from "@patternfly/patternfly/layouts/Flex/flex.css";
|
||||||
|
|
||||||
|
import { ExpiringBaseGrantModel, Oauth2Api, TokenModel } from "@goauthentik/api";
|
||||||
|
|
||||||
|
@customElement("ak-user-oauth-access-token-list")
|
||||||
|
export class UserOAuthAccessTokenList extends Table<TokenModel> {
|
||||||
|
expandable = true;
|
||||||
|
|
||||||
|
@property({ type: Number })
|
||||||
|
userId?: number;
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return super.styles.concat(PFFlex);
|
||||||
|
}
|
||||||
|
|
||||||
|
async apiEndpoint(page: number): Promise<PaginatedResponse<TokenModel>> {
|
||||||
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2AccessTokensList({
|
||||||
|
user: this.userId,
|
||||||
|
ordering: "expires",
|
||||||
|
page: page,
|
||||||
|
pageSize: (await uiConfig()).pagination.perPage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox = true;
|
||||||
|
order = "-expires";
|
||||||
|
|
||||||
|
columns(): TableColumn[] {
|
||||||
|
return [
|
||||||
|
new TableColumn(msg("Provider"), "provider"),
|
||||||
|
new TableColumn(msg("Revoked?"), "revoked"),
|
||||||
|
new TableColumn(msg("Expires"), "expires"),
|
||||||
|
new TableColumn(msg("Scopes"), "scope"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
renderExpanded(item: TokenModel): TemplateResult {
|
||||||
|
return html` <td role="cell" colspan="4">
|
||||||
|
<div class="pf-c-table__expandable-row-content">
|
||||||
|
<div class="pf-l-flex">
|
||||||
|
<div class="pf-l-flex__item">
|
||||||
|
<h3>${msg("ID Token")}</h3>
|
||||||
|
<pre>${item.idToken}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderToolbarSelected(): TemplateResult {
|
||||||
|
const disabled = this.selectedElements.length < 1;
|
||||||
|
return html`<ak-forms-delete-bulk
|
||||||
|
objectLabel=${msg("Refresh Tokens(s)")}
|
||||||
|
.objects=${this.selectedElements}
|
||||||
|
.usedBy=${(item: ExpiringBaseGrantModel) => {
|
||||||
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensUsedByList({
|
||||||
|
id: item.pk,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
.delete=${(item: ExpiringBaseGrantModel) => {
|
||||||
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensDestroy({
|
||||||
|
id: item.pk,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
${msg("Delete")}
|
||||||
|
</button>
|
||||||
|
</ak-forms-delete-bulk>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
row(item: TokenModel): TemplateResult[] {
|
||||||
|
return [
|
||||||
|
html`<a href="#/core/providers/${item.provider?.pk}"> ${item.provider?.name} </a>`,
|
||||||
|
html`<ak-status-label type="warning" ?good=${item.revoked}></ak-status-label>`,
|
||||||
|
html`${item.expires?.toLocaleString()}`,
|
||||||
|
html`${item.scope.join(", ")}`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -13,8 +13,8 @@ import PFFlex from "@patternfly/patternfly/layouts/Flex/flex.css";
|
|||||||
|
|
||||||
import { ExpiringBaseGrantModel, Oauth2Api, TokenModel } from "@goauthentik/api";
|
import { ExpiringBaseGrantModel, Oauth2Api, TokenModel } from "@goauthentik/api";
|
||||||
|
|
||||||
@customElement("ak-user-oauth-refresh-list")
|
@customElement("ak-user-oauth-refresh-token-list")
|
||||||
export class UserOAuthRefreshList extends Table<TokenModel> {
|
export class UserOAuthRefreshTokenList extends Table<TokenModel> {
|
||||||
expandable = true;
|
expandable = true;
|
||||||
|
|
||||||
@property({ type: Number })
|
@property({ type: Number })
|
@ -38,6 +38,7 @@ export class ObjectPermissionsPageForm extends ModelForm<unknown, string> {
|
|||||||
.model=${this.model}
|
.model=${this.model}
|
||||||
.objectPk=${this.objectPk}
|
.objectPk=${this.objectPk}
|
||||||
slot="form"
|
slot="form"
|
||||||
|
.embedded=${true}
|
||||||
>
|
>
|
||||||
</ak-rbac-object-permission-page>`;
|
</ak-rbac-object-permission-page>`;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
import "@goauthentik/app/admin/roles/RoleAssignedGlobalPermissionsTable";
|
||||||
|
import "@goauthentik/app/admin/roles/RoleAssignedObjectPermissionTable";
|
||||||
|
import "@goauthentik/app/admin/users/UserAssignedGlobalPermissionsTable";
|
||||||
|
import "@goauthentik/app/admin/users/UserAssignedObjectPermissionsTable";
|
||||||
import { AKElement } from "@goauthentik/app/elements/Base";
|
import { AKElement } from "@goauthentik/app/elements/Base";
|
||||||
import "@goauthentik/app/elements/rbac/RoleObjectPermissionTable";
|
import "@goauthentik/app/elements/rbac/RoleObjectPermissionTable";
|
||||||
import "@goauthentik/app/elements/rbac/UserObjectPermissionTable";
|
import "@goauthentik/app/elements/rbac/UserObjectPermissionTable";
|
||||||
import "@goauthentik/elements/Tabs";
|
import "@goauthentik/elements/Tabs";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, html } from "lit";
|
import { html, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
||||||
@ -24,20 +28,26 @@ export class ObjectPermissionPage extends AKElement {
|
|||||||
objectPk?: string | number;
|
objectPk?: string | number;
|
||||||
|
|
||||||
@property({ type: Boolean })
|
@property({ type: Boolean })
|
||||||
showBanner = true;
|
embedded = false;
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles() {
|
||||||
return [PFBase, PFGrid, PFPage, PFCard, PFBanner];
|
return [PFBase, PFGrid, PFPage, PFCard, PFBanner];
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render() {
|
||||||
return html`${this.showBanner
|
return html`${!this.embedded
|
||||||
? html`<div class="pf-c-banner pf-m-info">
|
? html`<div class="pf-c-banner pf-m-info">
|
||||||
${msg("RBAC is in preview.")}
|
${msg("RBAC is in preview.")}
|
||||||
<a href="mailto:hello@goauthentik.io">${msg("Send us feedback!")}</a>
|
<a href="mailto:hello@goauthentik.io">${msg("Send us feedback!")}</a>
|
||||||
</div>`
|
</div>`
|
||||||
: html``}
|
: nothing}
|
||||||
<ak-tabs pageIdentifier="permissionPage">
|
<ak-tabs pageIdentifier="permissionPage" ?vertical=${!this.embedded}>
|
||||||
|
${this.model === RbacPermissionsAssignedByUsersListModelEnum.CoreUser
|
||||||
|
? this.renderCoreUser()
|
||||||
|
: nothing}
|
||||||
|
${this.model === RbacPermissionsAssignedByUsersListModelEnum.RbacRole
|
||||||
|
? this.renderRbacRole()
|
||||||
|
: nothing}
|
||||||
<section
|
<section
|
||||||
slot="page-object-user"
|
slot="page-object-user"
|
||||||
data-tab-title="${msg("User Object Permissions")}"
|
data-tab-title="${msg("User Object Permissions")}"
|
||||||
@ -45,7 +55,10 @@ export class ObjectPermissionPage extends AKElement {
|
|||||||
>
|
>
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
<div class="pf-l-grid pf-m-gutter">
|
||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||||
<div class="pf-c-card__title">User Object Permissions</div>
|
<div class="pf-c-card__title">${msg("User Object Permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg("Permissions set on users which affect this object.")}
|
||||||
|
</div>
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-rbac-user-object-permission-table
|
<ak-rbac-user-object-permission-table
|
||||||
.model=${this.model}
|
.model=${this.model}
|
||||||
@ -63,7 +76,10 @@ export class ObjectPermissionPage extends AKElement {
|
|||||||
>
|
>
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
<div class="pf-l-grid pf-m-gutter">
|
||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||||
<div class="pf-c-card__title">Role Object Permissions</div>
|
<div class="pf-c-card__title">${msg("Role Object Permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg("Permissions set on roles which affect this object.")}
|
||||||
|
</div>
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-rbac-role-object-permission-table
|
<ak-rbac-role-object-permission-table
|
||||||
.model=${this.model}
|
.model=${this.model}
|
||||||
@ -76,4 +92,98 @@ export class ObjectPermissionPage extends AKElement {
|
|||||||
</section>
|
</section>
|
||||||
</ak-tabs>`;
|
</ak-tabs>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderCoreUser() {
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
slot="page-assigned-global-permissions"
|
||||||
|
data-tab-title="${msg("Assigned global permissions")}"
|
||||||
|
>
|
||||||
|
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__title">${msg("Assigned global permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg(
|
||||||
|
"Permissions assigned to this user which affect all object instances of a given type.",
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-assigned-global-permissions-table
|
||||||
|
userId=${this.objectPk as number}
|
||||||
|
>
|
||||||
|
</ak-user-assigned-global-permissions-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
slot="page-assigned-object-permissions"
|
||||||
|
data-tab-title="${msg("Assigned object permissions")}"
|
||||||
|
>
|
||||||
|
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__title">${msg("Assigned object permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg(
|
||||||
|
"Permissions assigned to this user affecting specific object instances.",
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-user-assigned-object-permissions-table
|
||||||
|
userId=${this.objectPk as number}
|
||||||
|
>
|
||||||
|
</ak-user-assigned-object-permissions-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRbacRole() {
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
slot="page-assigned-global-permissions"
|
||||||
|
data-tab-title="${msg("Assigned global permissions")}"
|
||||||
|
>
|
||||||
|
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__title">${msg("Assigned global permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg(
|
||||||
|
"Permissions assigned to this role which affect all object instances of a given type.",
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-role-assigned-global-permissions-table
|
||||||
|
roleUuid=${this.objectPk as string}
|
||||||
|
>
|
||||||
|
</ak-role-assigned-global-permissions-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
slot="page-assigned-object-permissions"
|
||||||
|
data-tab-title="${msg("Assigned object permissions")}"
|
||||||
|
>
|
||||||
|
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
|
||||||
|
<div class="pf-c-card">
|
||||||
|
<div class="pf-c-card__title">${msg("Assigned object permissions")}</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
${msg(
|
||||||
|
"Permissions assigned to this user affecting specific object instances.",
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="pf-c-card__body">
|
||||||
|
<ak-role-assigned-object-permissions-table
|
||||||
|
roleUuid=${this.objectPk as string}
|
||||||
|
>
|
||||||
|
</ak-role-assigned-object-permissions-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,12 @@ export abstract class Table<T> extends AKElement implements TableLike {
|
|||||||
.pf-c-table tbody .pf-c-table__check input {
|
.pf-c-table tbody .pf-c-table__check input {
|
||||||
margin-top: calc(var(--pf-c-table__check--input--MarginTop) + 1px);
|
margin-top: calc(var(--pf-c-table__check--input--MarginTop) + 1px);
|
||||||
}
|
}
|
||||||
|
.pf-c-toolbar__content {
|
||||||
|
row-gap: var(--pf-global--spacer--sm);
|
||||||
|
}
|
||||||
|
.pf-c-toolbar__item .pf-c-input-group {
|
||||||
|
padding: 0 var(--pf-global--spacer--sm);
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
import { getRelativeTime } from "@goauthentik/app/common/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
|
import getUnicodeFlagIcon from "country-flag-icons/unicode";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { TemplateResult, html } from "lit";
|
import { TemplateResult, html } from "lit";
|
||||||
@ -31,6 +33,7 @@ export class AuthenticatedSessionList extends Table<AuthenticatedSession> {
|
|||||||
columns(): TableColumn[] {
|
columns(): TableColumn[] {
|
||||||
return [
|
return [
|
||||||
new TableColumn(msg("Last IP"), "last_ip"),
|
new TableColumn(msg("Last IP"), "last_ip"),
|
||||||
|
new TableColumn(msg("Last used"), "last_used"),
|
||||||
new TableColumn(msg("Expires"), "expires"),
|
new TableColumn(msg("Expires"), "expires"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -66,10 +69,17 @@ export class AuthenticatedSessionList extends Table<AuthenticatedSession> {
|
|||||||
row(item: AuthenticatedSession): TemplateResult[] {
|
row(item: AuthenticatedSession): TemplateResult[] {
|
||||||
return [
|
return [
|
||||||
html`<div>
|
html`<div>
|
||||||
${item.current ? html`${msg("(Current session)")} ` : html``}${item.lastIp}
|
${item.current ? html`${msg("(Current session)")} ` : html``}
|
||||||
|
${item.lastIp}
|
||||||
|
${item.geoIp?.country
|
||||||
|
? html` ${getUnicodeFlagIcon(item.geoIp.country)} `
|
||||||
|
: html``}
|
||||||
</div>
|
</div>
|
||||||
<small>${item.userAgent.userAgent?.family}, ${item.userAgent.os?.family}</small>`,
|
<small>${item.userAgent.userAgent?.family}, ${item.userAgent.os?.family}</small>`,
|
||||||
html`${item.expires?.toLocaleString()}`,
|
html`<div>${getRelativeTime(item.lastUsed)}</div>
|
||||||
|
<small>${item.lastUsed?.toLocaleString()}</small>`,
|
||||||
|
html`<div>${getRelativeTime(item.expires || new Date())}</div>
|
||||||
|
<small>${item.expires?.toLocaleString()}</small>`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { TemplateResult, html } from "lit";
|
|||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
|
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
|
||||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||||
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
||||||
@ -32,7 +33,7 @@ export class PlexLoginInit extends BaseStage<
|
|||||||
authUrl?: string;
|
authUrl?: string;
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle];
|
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, PFDivider];
|
||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
@ -76,7 +77,7 @@ export class PlexLoginInit extends BaseStage<
|
|||||||
header=${msg("Waiting for authentication...")}
|
header=${msg("Waiting for authentication...")}
|
||||||
>
|
>
|
||||||
</ak-empty-state>
|
</ak-empty-state>
|
||||||
<hr />
|
<hr class="pf-c-divider" />
|
||||||
<p>${msg("If no Plex popup opens, click the button below.")}</p>
|
<p>${msg("If no Plex popup opens, click the button below.")}</p>
|
||||||
<button
|
<button
|
||||||
class="pf-c-button pf-m-block pf-m-primary"
|
class="pf-c-button pf-m-block pf-m-primary"
|
||||||
|
@ -8,6 +8,7 @@ import { CSSResult, TemplateResult, css, html } from "lit";
|
|||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
|
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
|
||||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||||
@ -26,6 +27,7 @@ export class AccessDeniedIcon extends AKElement {
|
|||||||
return [
|
return [
|
||||||
PFBase,
|
PFBase,
|
||||||
PFTitle,
|
PFTitle,
|
||||||
|
PFDivider,
|
||||||
css`
|
css`
|
||||||
.big-icon {
|
.big-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -51,7 +53,7 @@ export class AccessDeniedIcon extends AKElement {
|
|||||||
</p>
|
</p>
|
||||||
<h3 class="pf-c-title pf-m-3xl reason">${msg("Request has been denied.")}</h3>
|
<h3 class="pf-c-title pf-m-3xl reason">${msg("Request has been denied.")}</h3>
|
||||||
${this.errorMessage
|
${this.errorMessage
|
||||||
? html`<hr />
|
? html` <hr class="pf-c-divider" />
|
||||||
<p>${this.errorMessage}</p>`
|
<p>${this.errorMessage}</p>`
|
||||||
: html``}
|
: html``}
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@ -121,6 +121,9 @@ export class UserInterface extends Interface {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.pf-c-drawer__main {
|
||||||
|
max-height: calc(100vh - 76px);
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -427,12 +427,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>Keine Worker verbunden. Hintergrundaufgaben werden nicht ausgeführt.</target>
|
<target>Keine Worker verbunden. Hintergrundaufgaben werden nicht ausgeführt.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>Berechtigungen</target>
|
<target>Berechtigungen</target>
|
||||||
@ -5834,9 +5828,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6372,6 +6363,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -433,16 +433,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>No workers connected. Background tasks will not run.</target>
|
<target>No workers connected. Background tasks will not run.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/>hour(s) ago</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/>day(s) ago</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>Authorizations</target>
|
<target>Authorizations</target>
|
||||||
@ -6109,9 +6099,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6647,6 +6634,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -420,12 +420,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>No hay trabajadores conectados. No se ejecutarán tareas en segundo plano.</target>
|
<target>No hay trabajadores conectados. No se ejecutarán tareas en segundo plano.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>Autorizaciones</target>
|
<target>Autorizaciones</target>
|
||||||
@ -5750,9 +5744,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6288,6 +6279,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -537,18 +537,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>Aucun worker connecté. Les tâches de fond ne tourneront pas.</target>
|
<target>Aucun worker connecté. Les tâches de fond ne tourneront pas.</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target>
|
|
||||||
Il y a <x id="0" equiv-text="${ago}"/> heure(s)</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target>
|
|
||||||
Il y a <x id="0" equiv-text="${ago}"/> jour(s)</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7666,10 +7654,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
<target>L'utilisateur n'a pas les permissions de lecture, la description ne peut donc pas être récupérée.</target>
|
<target>L'utilisateur n'a pas les permissions de lecture, la description ne peut donc pas être récupérée.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
<target>Permissions assignées</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
<target>Permissions globales assignées</target>
|
<target>Permissions globales assignées</target>
|
||||||
@ -8375,6 +8359,30 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -536,18 +536,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>연결된 워커가 없습니다. 백그라운드 작업이 실행되지 않습니다.</target>
|
<target>연결된 워커가 없습니다. 백그라운드 작업이 실행되지 않습니다.</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/>시간 전</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/> 일 전</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7629,10 +7617,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
<target>사용자에게 보기 권한이 없으므로 설명을 검색할 수 없습니다.</target>
|
<target>사용자에게 보기 권한이 없으므로 설명을 검색할 수 없습니다.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
<target>할당된 권한</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
<target>전역 권한 할당</target>
|
<target>전역 권한 할당</target>
|
||||||
@ -8245,6 +8229,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -530,16 +530,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>Geen medewerkers verbonden. Achtergrondtaken worden niet uitgevoerd.</target>
|
<target>Geen medewerkers verbonden. Achtergrondtaken worden niet uitgevoerd.</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> uur geleden</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> dag(en) geleden</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7769,9 +7759,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
|||||||
<trans-unit id="se5c795faf2c07514">
|
<trans-unit id="se5c795faf2c07514">
|
||||||
<source>Create Recovery Link</source>
|
<source>Create Recovery Link</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -8085,6 +8072,30 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -429,12 +429,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>Brak połączonych workerów. Zadania w tle nie będą działać.</target>
|
<target>Brak połączonych workerów. Zadania w tle nie będą działać.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>Autoryzacje</target>
|
<target>Autoryzacje</target>
|
||||||
@ -5957,9 +5951,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6495,6 +6486,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -531,16 +531,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>Ńō ŵōŕķēŕś ćōńńēćţēď. ßàćķĝŕōũńď ţàśķś ŵĩĺĺ ńōţ ŕũń.</target>
|
<target>Ńō ŵōŕķēŕś ćōńńēćţēď. ßàćķĝŕōũńď ţàśķś ŵĩĺĺ ńōţ ŕũń.</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> ĥōũŕ(ś) àĝō</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> ďàŷ(ś) àĝō</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7609,10 +7599,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
<target>Ũśēŕ ďōēśń'ţ ĥàvē vĩēŵ ƥēŕmĩśśĩōń śō ďēśćŕĩƥţĩōń ćàńńōţ ƀē ŕēţŕĩēvēď.</target>
|
<target>Ũśēŕ ďōēśń'ţ ĥàvē vĩēŵ ƥēŕmĩśśĩōń śō ďēśćŕĩƥţĩōń ćàńńōţ ƀē ŕēţŕĩēvēď.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
<target>Àśśĩĝńēď ƥēŕmĩśśĩōńś</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
<target>Àśśĩĝńēď ĝĺōƀàĺ ƥēŕmĩśśĩōńś</target>
|
<target>Àśśĩĝńēď ĝĺōƀàĺ ƥēŕmĩśśĩōńś</target>
|
||||||
@ -8220,4 +8206,28 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
</body></file></xliff>
|
</body></file></xliff>
|
||||||
|
@ -420,12 +420,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>İşçi bağlantısı yok. Arka plan görevleri çalışmaz.</target>
|
<target>İşçi bağlantısı yok. Arka plan görevleri çalışmaz.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>Yetkilendirmeler</target>
|
<target>Yetkilendirmeler</target>
|
||||||
@ -5743,9 +5737,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6281,6 +6272,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -344,15 +344,9 @@
|
|||||||
<trans-unit id="s341ab68d4130de20">
|
<trans-unit id="s341ab68d4130de20">
|
||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s98327528f00365a7">
|
<trans-unit id="s98327528f00365a7">
|
||||||
<source>Failed to fetch data.</source>
|
<source>Failed to fetch data.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -3169,9 +3163,6 @@ doesn't pass when either or both of the selected options are equal or above the
|
|||||||
<trans-unit id="s28b3de1561da72b3">
|
<trans-unit id="s28b3de1561da72b3">
|
||||||
<source>MFA Authenticators</source>
|
<source>MFA Authenticators</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -5191,6 +5182,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -537,18 +537,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>没有 Workers 连接,后台任务将无法运行。</target>
|
<target>没有 Workers 连接,后台任务将无法运行。</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/>小时前</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target>
|
|
||||||
<x id="0" equiv-text="${ago}"/>天前</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7668,10 +7656,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
<target>用户不具有查看权限,所以无法获取描述。</target>
|
<target>用户不具有查看权限,所以无法获取描述。</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
<target>分配的权限</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
<target>分配的全局权限</target>
|
<target>分配的全局权限</target>
|
||||||
@ -8388,6 +8372,42 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sb2275335377069aa">
|
||||||
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -427,12 +427,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>没有 workers 连接。后台任务将无法运行。</target>
|
<target>没有 workers 连接。后台任务将无法运行。</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
<target>授权</target>
|
<target>授权</target>
|
||||||
@ -5791,9 +5785,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s1455753daa00f1bc">
|
<trans-unit id="s1455753daa00f1bc">
|
||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -6329,6 +6320,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -530,16 +530,6 @@
|
|||||||
<source>No workers connected. Background tasks will not run.</source>
|
<source>No workers connected. Background tasks will not run.</source>
|
||||||
<target>沒有已連線的 workers,無法執行背景工作。</target>
|
<target>沒有已連線的 workers,無法執行背景工作。</target>
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s2ed8eb02525a920a">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> 小時以前</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s1f1c857c0c4250e4">
|
|
||||||
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
|
|
||||||
<target><x id="0" equiv-text="${ago}"/> 天以前</target>
|
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s11bc220e8fa9d797">
|
<trans-unit id="s11bc220e8fa9d797">
|
||||||
<source>Authorizations</source>
|
<source>Authorizations</source>
|
||||||
@ -7602,10 +7592,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
<source>User doesn't have view permission so description cannot be retrieved.</source>
|
||||||
<target>使用者沒有讀取權限,所以無法取得描述。</target>
|
<target>使用者沒有讀取權限,所以無法取得描述。</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sa3a3e09b88ed9791">
|
|
||||||
<source>Assigned permissions</source>
|
|
||||||
<target>已分配的權限</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="s9cc631505c17b028">
|
<trans-unit id="s9cc631505c17b028">
|
||||||
<source>Assigned global permissions</source>
|
<source>Assigned global permissions</source>
|
||||||
<target>已分配的全域權限</target>
|
<target>已分配的全域權限</target>
|
||||||
@ -8204,6 +8190,30 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sb2275335377069aa">
|
<trans-unit id="sb2275335377069aa">
|
||||||
<source>This feature requires an enterprise license.</source>
|
<source>This feature requires an enterprise license.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s6d3f81dc4bcacbda">
|
||||||
|
<source>Last used</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s96b2703420bfbd0c">
|
||||||
|
<source>OAuth Access Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sd99e668c54f78f6e">
|
||||||
|
<source>Credentials / Tokens</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="saada50e84c7c646d">
|
||||||
|
<source>Permissions set on users which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s37d1b74df205b528">
|
||||||
|
<source>Permissions set on roles which affect this object.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="sc443bfff8a5dd106">
|
||||||
|
<source>Permissions assigned to this user which affect all object instances of a given type.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3eba09a350b7d6c9">
|
||||||
|
<source>Permissions assigned to this user affecting specific object instances.</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s17032e57ba222d2f">
|
||||||
|
<source>Permissions assigned to this role which affect all object instances of a given type.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -9,22 +9,20 @@ Refer to the following topics for instructions to view and manage permissions.
|
|||||||
|
|
||||||
You can view all permissions that are assigned to a user, group, role, flow, or stage.
|
You can view all permissions that are assigned to a user, group, role, flow, or stage.
|
||||||
|
|
||||||
### View user, group, and role permissions
|
### View user and role permissions
|
||||||
|
|
||||||
To view _object_ permissions for a specific user, role, or group:
|
To view _object_ permissions for a specific user or role:
|
||||||
|
|
||||||
1. Go to the Admin interface and navigate to **Directory**.
|
1. Go to the Admin interface and navigate to **Directory**.
|
||||||
2. Select either **Users**, **Groups**, or **Roles**
|
2. Select either **Users** or **Roles**
|
||||||
3. Select a specific user/group/role by clicking on the name (this opens the details page).
|
3. Select a specific user/role by clicking on the name (this opens the details page).
|
||||||
4. Click the **Assigned Permissions** tab at the top of the page (to the right of the **Permissions** tab).
|
4. Click the **Permissions** tab at the top of the page
|
||||||
5. Scroll down to see both the global and object-level permissions.
|
5. Select the **Assigned global permissions** sub-tab to see global permissions and the **Assigned object permissions** sub-tab to see the object-level permissions.
|
||||||
|
|
||||||
:::info
|
|
||||||
Note that groups do not have global permissions.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### View flow permissions
|
### View flow permissions
|
||||||
|
|
||||||
|
\_These instructions apply to all objects that have a detail page, which can be accessed by clicking on the name in the list page.\_\_
|
||||||
|
|
||||||
1. Go to the Admin interface and navigate to **Flows and Stages -> Flows**.
|
1. Go to the Admin interface and navigate to **Flows and Stages -> Flows**.
|
||||||
2. Click the name of the flow (this opens the details page).
|
2. Click the name of the flow (this opens the details page).
|
||||||
3. Click the **Permissions** tab at the top of the page.
|
3. Click the **Permissions** tab at the top of the page.
|
||||||
@ -32,6 +30,8 @@ Note that groups do not have global permissions.
|
|||||||
|
|
||||||
### View stage permissions
|
### View stage permissions
|
||||||
|
|
||||||
|
\_These instructions apply to all objects that **do not** have a detail page.\_\_
|
||||||
|
|
||||||
1. Go to the Admin interface and navigate to **Flows and Stages -> Stagess**.
|
1. Go to the Admin interface and navigate to **Flows and Stages -> Stagess**.
|
||||||
2. On the row for the specific stage whose permissions you want to view, click the lock icon.
|
2. On the row for the specific stage whose permissions you want to view, click the lock icon.
|
||||||
3. On the **Update Permissions** tab, you can view the assigned permissions using the **User Object Permissions** and the **Role Object Permissions** tabs.
|
3. On the **Update Permissions** tab, you can view the assigned permissions using the **User Object Permissions** and the **Role Object Permissions** tabs.
|
||||||
|
Reference in New Issue
Block a user