Introduce authorizations with Rajska
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -65,18 +65,15 @@
|
||||
</o-field>
|
||||
<o-modal
|
||||
has-modal-card
|
||||
v-model="showNewElementModal"
|
||||
v-model:active="showNewElementModal"
|
||||
:close-button-aria-label="$t('Close')"
|
||||
>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<button
|
||||
type="button"
|
||||
class="delete"
|
||||
@click="showNewElementModal = false"
|
||||
/>
|
||||
<div class="">
|
||||
<header class="">
|
||||
<h2>{{ t('Create a new metadata element') }}</h2>
|
||||
<p>{{ t('You can put any arbitrary content in this element. URLs will be clickable.') }}</p>
|
||||
</header>
|
||||
<div class="modal-card-body">
|
||||
<div class="">
|
||||
<form @submit="addNewElement">
|
||||
<o-field :label="$t('Element title')">
|
||||
<o-input v-model="newElement.title" />
|
||||
@@ -84,7 +81,7 @@
|
||||
<o-field :label="$t('Element value')">
|
||||
<o-input v-model="newElement.value" />
|
||||
</o-field>
|
||||
<o-button variant="primary" native-type="submit">{{
|
||||
<o-button class="mt-2" variant="primary" native-type="submit">{{
|
||||
$t("Add")
|
||||
}}</o-button>
|
||||
</form>
|
||||
|
||||
@@ -70,7 +70,7 @@ function setupApp({ app }) {
|
||||
new Promise((resolve) =>
|
||||
resolve({
|
||||
data: {
|
||||
identities: [{ id: "9", preferredUsername: "sam", name: "Samuel" }],
|
||||
loggedUser: { actors: [{ id: "9", preferredUsername: "sam", name: "Samuel" }] },
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
@@ -1,44 +1,94 @@
|
||||
<template>
|
||||
<h1 class="text-3xl">
|
||||
{{ t("Autorize this application to access your account?") }}
|
||||
</h1>
|
||||
<div>
|
||||
<h1 class="text-3xl">
|
||||
{{ t("Autorize this application to access your account?") }}
|
||||
</h1>
|
||||
|
||||
<div
|
||||
class="rounded-lg bg-mbz-warning dark:text-black shadow-xl my-6 p-4 flex items-center gap-2"
|
||||
>
|
||||
<AlertCircle :size="42" />
|
||||
<p>
|
||||
{{
|
||||
t(
|
||||
"This application will be able to access all of your informations and post content on your behalf. Make sure you only approve applications you trust."
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-xl my-6">
|
||||
<div class="p-4 pb-0">
|
||||
<p class="text-3xl font-bold">{{ authApplication.name }}</p>
|
||||
<p>{{ authApplication.website }}</p>
|
||||
</div>
|
||||
<div class="flex gap-3 p-4">
|
||||
<o-button @click="() => authorize()">{{ t("Authorize") }}</o-button>
|
||||
<o-button outlined tag="router-link" :to="{ name: RouteName.HOME }">{{
|
||||
t("Decline")
|
||||
}}</o-button>
|
||||
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-xl my-6">
|
||||
<div class="p-4 pb-0">
|
||||
<p class="text-3xl font-bold">{{ authApplication.name }}</p>
|
||||
<p>{{ authApplication.website }}</p>
|
||||
</div>
|
||||
<p class="p-4">
|
||||
{{
|
||||
t(
|
||||
"You'll be able to revoke access for this application in your account settings."
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<div class="">
|
||||
<div
|
||||
v-if="collapses.length === 0"
|
||||
class="rounded-lg bg-mbz-danger shadow-xl my-6 p-4 flex items-center gap-2"
|
||||
>
|
||||
<AlertCircle :size="42" />
|
||||
<p>
|
||||
{{
|
||||
t(
|
||||
"This application didn't ask for known permissions. It's likely the request is incorrect."
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<p v-else class="px-4 font-bold">
|
||||
{{ t('This application asks for the following permissions:') }}
|
||||
</p>
|
||||
<o-collapse
|
||||
class="mt-3 border-b pb-2 border-zinc-700 text-black dark:text-white"
|
||||
:class="{
|
||||
'bg-mbz-warning dark:!text-black': collapse?.type === 'warning',
|
||||
}"
|
||||
animation="slide"
|
||||
v-for="(collapse, index) of collapses"
|
||||
:key="index"
|
||||
:open="isOpen === index"
|
||||
@open="isOpen = index"
|
||||
>
|
||||
<template #trigger="props">
|
||||
<div class="flex py-1" role="button">
|
||||
<o-icon :icon="collapse.icon" class="px-2" />
|
||||
<p class="font-bold text-lg p-2 flex-1">
|
||||
{{ collapse.title }}
|
||||
</p>
|
||||
<a
|
||||
class="flex items-center cursor-pointer p-3 justify-center self-end"
|
||||
>
|
||||
<o-icon :icon="props.open ? 'chevron-up' : 'chevron-down'">
|
||||
</o-icon>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<div class="p-2">
|
||||
<div class="content">
|
||||
{{ collapse.text }}
|
||||
</div>
|
||||
</div>
|
||||
</o-collapse>
|
||||
</div>
|
||||
<div class="flex gap-3 p-4">
|
||||
<o-button
|
||||
:disabled="collapses.length === 0"
|
||||
@click="() => authorize()"
|
||||
>{{ t("Authorize") }}</o-button
|
||||
>
|
||||
<o-button outlined tag="router-link" :to="{ name: RouteName.HOME }">{{
|
||||
t("Decline")
|
||||
}}</o-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useHead } from "@vueuse/head";
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useMutation } from "@vue/apollo-composable";
|
||||
import { AUTORIZE_APPLICATION } from "@/graphql/application";
|
||||
import AlertCircle from "vue-material-design-icons/AlertCircle.vue";
|
||||
import RouteName from "@/router/name";
|
||||
import { IApplication } from "@/types/application.model";
|
||||
import { scope } from "./scope";
|
||||
import AlertCircle from "vue-material-design-icons/AlertCircle.vue";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
@@ -49,9 +99,25 @@ const props = defineProps<{
|
||||
scope?: string | null;
|
||||
}>();
|
||||
|
||||
const isOpen = ref<number>(-1);
|
||||
|
||||
const collapses = computed(() =>
|
||||
(props.scope ?? "")
|
||||
.split(" ")
|
||||
.map((scope) => scope[scope])
|
||||
.filter((scope) => scope)
|
||||
);
|
||||
|
||||
const { mutate: authorizeMutation, onDone: onAuthorizeMutationDone } =
|
||||
useMutation<
|
||||
{ authorizeApplication: { code: string; state: string } },
|
||||
{
|
||||
authorizeApplication: {
|
||||
code: string;
|
||||
state: string;
|
||||
clientId: string;
|
||||
scope: string;
|
||||
};
|
||||
},
|
||||
{
|
||||
applicationClientId: string;
|
||||
redirectURI: string;
|
||||
@@ -71,13 +137,20 @@ const authorize = () => {
|
||||
|
||||
onAuthorizeMutationDone(({ data }) => {
|
||||
const code = data?.authorizeApplication?.code;
|
||||
const localClientId = data?.authorizeApplication?.clientId;
|
||||
const localScope = data?.authorizeApplication?.scope;
|
||||
const returnedState = data?.authorizeApplication?.state ?? "";
|
||||
|
||||
if (!code) return;
|
||||
if (!code || !localClientId || !localScope) return;
|
||||
|
||||
if (props.redirectURI) {
|
||||
const params = new URLSearchParams(
|
||||
Object.entries({ code, state: returnedState })
|
||||
Object.entries({
|
||||
code,
|
||||
state: returnedState,
|
||||
client_id: localClientId,
|
||||
scope: localScope,
|
||||
})
|
||||
);
|
||||
window.location.assign(
|
||||
new URL(`${props.redirectURI}?${params.toString()}`)
|
||||
|
||||
283
js/src/components/OAuth/scopes.ts
Normal file
283
js/src/components/OAuth/scopes.ts
Normal file
@@ -0,0 +1,283 @@
|
||||
import { i18n } from "@/utils/i18n";
|
||||
|
||||
const t = i18n.global.t;
|
||||
|
||||
export const scope: Record<
|
||||
string,
|
||||
{ title: string; type?: "warning"; text: string; icon?: string }
|
||||
> = {
|
||||
read: {
|
||||
title: t("Read all of your account's data"),
|
||||
type: "warning",
|
||||
text: t(
|
||||
"This application will be allowed to see all of your events organized, the events you participate to, as well as every data from your groups."
|
||||
),
|
||||
icon: "eye-outline",
|
||||
},
|
||||
write: {
|
||||
title: t("Modify all of your account's data"),
|
||||
text: t(
|
||||
"This application will be allowed to publish and manage events on your behalf, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings."
|
||||
),
|
||||
type: "warning",
|
||||
icon: "pencil-outline",
|
||||
},
|
||||
"write:event:create": {
|
||||
title: t("Publish events"),
|
||||
text: t(
|
||||
"This application will be allowed to publish events on your behalf"
|
||||
),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:event:update": {
|
||||
title: t("Update events"),
|
||||
text: t("This application will be allowed to update events on your behalf"),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:event:delete": {
|
||||
title: t("Delete events"),
|
||||
text: t("This application will be allowed to delete events on your behalf"),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:media:upload": {
|
||||
title: t("Upload media"),
|
||||
text: t("This application will be allowed to upload media on your behalf"),
|
||||
icon: "image",
|
||||
},
|
||||
"write:media:remove": {
|
||||
title: t("Remove uploaded media"),
|
||||
text: t(
|
||||
"This application will be allowed to remove uploaded media on your behalf"
|
||||
),
|
||||
icon: "image",
|
||||
},
|
||||
"write:group:post:create": {
|
||||
title: t("Publish group posts"),
|
||||
text: t(
|
||||
"This application will be allowed to publish group posts on your behalf"
|
||||
),
|
||||
icon: "bullhorn",
|
||||
},
|
||||
"write:group:post:update": {
|
||||
title: t("Update group posts"),
|
||||
text: t(
|
||||
"This application will be allowed to update group posts on your behalf"
|
||||
),
|
||||
icon: "bullhorn",
|
||||
},
|
||||
"write:group:post:delete": {
|
||||
title: t("Delete group posts"),
|
||||
text: t(
|
||||
"This application will be allowed to delete group posts on your behalf"
|
||||
),
|
||||
icon: "bullhorn",
|
||||
},
|
||||
"read:group:resources": {
|
||||
title: t("Access your group's resources"),
|
||||
text: t(
|
||||
"This application will be allowed to access all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "link",
|
||||
},
|
||||
"write:group:resources:create": {
|
||||
title: t("Create group resources"),
|
||||
text: t(
|
||||
"This application will be allowed to create resources in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "link",
|
||||
},
|
||||
"write:group:resources:update": {
|
||||
title: t("Update group resources"),
|
||||
text: t(
|
||||
"This application will be allowed to update resources in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "link",
|
||||
},
|
||||
"write:group:resources:delete": {
|
||||
title: t("Delete group resources"),
|
||||
text: t(
|
||||
"This application will be allowed to delete resources in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "link",
|
||||
},
|
||||
"read:group:events": {
|
||||
title: t("Access group events"),
|
||||
text: t(
|
||||
"This application will be allowed to list and access group events in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "calendar",
|
||||
},
|
||||
"read:group:discussions": {
|
||||
title: t("Access group discussions"),
|
||||
text: t(
|
||||
"This application will be allowed to list and access group discussions in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "chat",
|
||||
},
|
||||
"read:group:members": {
|
||||
title: t("Access group members"),
|
||||
text: t(
|
||||
"This application will be allowed to list group members in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:group:followers": {
|
||||
title: t("Access group followers"),
|
||||
text: t(
|
||||
"This application will be allowed to list group followers in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:group:activities": {
|
||||
title: t("Access group activities"),
|
||||
text: t(
|
||||
"This application will be allowed to access group activities in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "timeline-text",
|
||||
},
|
||||
"read:group:todo_lists": {
|
||||
title: t("Access group todo-lists"),
|
||||
text: t(
|
||||
"This application will be allowed to list and access group todo-lists in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "checkbox-marked",
|
||||
},
|
||||
"write:group:group_membership": {
|
||||
title: t("Manage group memberships"),
|
||||
text: t(
|
||||
"This application will be allowed to join and leave groups on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:group:members": {
|
||||
title: t("Manage group members"),
|
||||
text: t(
|
||||
"This application will be allowed to manage group members in all of the groups you're a member of on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:profile:organized_events": {
|
||||
title: t("Access organized events"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view your organized events"
|
||||
),
|
||||
icon: "calendar",
|
||||
},
|
||||
"read:profile:participations": {
|
||||
title: t("Access participations"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view the events you're participating to"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:profile:memberships": {
|
||||
title: t("Access memberships"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view the groups you're a member of"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:profile:follows": {
|
||||
title: t("Access followed groups"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view the groups you're following"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:profile:create": {
|
||||
title: t("Create new profiles"),
|
||||
text: t(
|
||||
"This application will be allowed to create new profiles for your account on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:profile:update": {
|
||||
title: t("Update profiles"),
|
||||
text: t(
|
||||
"This application will be allowed to update your profiles on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:profile:delete": {
|
||||
title: t("Delete profiles"),
|
||||
text: t(
|
||||
"This application will be allowed to delete your profiles on your behalf"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:comment:create": {
|
||||
title: t("Post comments"),
|
||||
text: t("This application will be allowed to post comments on your behalf"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:comment:update": {
|
||||
title: t("Update comments"),
|
||||
text: t(
|
||||
"This application will be allowed to update comments on your behalf"
|
||||
),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:comment:delete": {
|
||||
title: t("Delete comments"),
|
||||
text: t(
|
||||
"This application will be allowed to delete comments on your behalf"
|
||||
),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:create": {
|
||||
title: t("Create group discussions"),
|
||||
text: t(
|
||||
"This application will be allowed to create group discussions on your behalf"
|
||||
),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:update": {
|
||||
title: t("Update group discussions"),
|
||||
text: t(
|
||||
"This application will be allowed to update group discussions on your behalf"
|
||||
),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:delete": {
|
||||
title: t("Delete group discussions"),
|
||||
text: t(
|
||||
"This application will be allowed to delete group discussions on your behalf"
|
||||
),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:profile:feed_token:create": {
|
||||
title: t("Create feed tokens"),
|
||||
text: t(
|
||||
"This application will be allowed to create feed tokens on your behalf"
|
||||
),
|
||||
icon: "rss",
|
||||
},
|
||||
"write:feed_token:delete": {
|
||||
title: t("Delete feed tokens"),
|
||||
text: t(
|
||||
"This application will be allowed to delete feed tokens on your behalf"
|
||||
),
|
||||
icon: "rss",
|
||||
},
|
||||
"write:participation": {
|
||||
title: t("Manage event participations"),
|
||||
text: t(
|
||||
"This application will be allowed to manage events participations on your behalf"
|
||||
),
|
||||
icon: "rss",
|
||||
},
|
||||
"write:user:setting:activity": {
|
||||
title: t("Manage activity settings"),
|
||||
text: t(
|
||||
"This application will be allowed to manage your account activity settings"
|
||||
),
|
||||
icon: "cog",
|
||||
},
|
||||
"write:user:setting:push": {
|
||||
title: t("Manage push notification settings"),
|
||||
text: t(
|
||||
"This application will be allowed to manage your account push notification settings"
|
||||
),
|
||||
icon: "cog",
|
||||
},
|
||||
};
|
||||
@@ -250,6 +250,14 @@ const icons: Record<string, () => Promise<any>> = {
|
||||
),
|
||||
ExitToApp: () =>
|
||||
import(`../../../node_modules/vue-material-design-icons/ExitToApp.vue`),
|
||||
CheckboxMarked: () =>
|
||||
import(
|
||||
`../../../node_modules/vue-material-design-icons/CheckboxMarked.vue`
|
||||
),
|
||||
EyeOutline: () =>
|
||||
import(`../../../node_modules/vue-material-design-icons/EyeOutline.vue`),
|
||||
PencilOutline: () =>
|
||||
import(`../../../node_modules/vue-material-design-icons/PencilOutline.vue`),
|
||||
};
|
||||
|
||||
const props = withDefaults(
|
||||
|
||||
Reference in New Issue
Block a user