build: switch from yarn to npm to manage js dependencies and move js contents to root
yarn v1 is being deprecated and starts to have some issues Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
227
src/components/OAuth/AuthorizeApplication.vue
Normal file
227
src/components/OAuth/AuthorizeApplication.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div v-if="checkDevice">
|
||||
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-xl my-6 p-4 pt-1">
|
||||
<h1 class="text-3xl">
|
||||
{{ t("Application authorized") }}
|
||||
</h1>
|
||||
<p>
|
||||
{{ t("Check your device to continue. You may now close this window.") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h1 class="text-3xl">
|
||||
{{ t("Autorize this application to access your account?") }}
|
||||
</h1>
|
||||
|
||||
<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="() => (userCode ? authorizeDevice() : 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, inject, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useMutation } from "@vue/apollo-composable";
|
||||
import {
|
||||
AUTORIZE_APPLICATION,
|
||||
AUTORIZE_DEVICE_APPLICATION,
|
||||
} from "@/graphql/application";
|
||||
import RouteName from "@/router/name";
|
||||
import { IApplication } from "@/types/application.model";
|
||||
import { scope as oAuthScopes } from "./scopes";
|
||||
import AlertCircle from "vue-material-design-icons/AlertCircle.vue";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const props = defineProps<{
|
||||
authApplication: IApplication;
|
||||
redirectURI?: string | null;
|
||||
state?: string | null;
|
||||
scope?: string | null;
|
||||
userCode?: string;
|
||||
}>();
|
||||
|
||||
const isOpen = ref<number>(-1);
|
||||
const checkDevice = ref(false);
|
||||
|
||||
const collapses = computed(() =>
|
||||
(props.scope ?? "")
|
||||
.split(" ")
|
||||
.map((localScope) => oAuthScopes[localScope])
|
||||
.filter((localScope) => localScope)
|
||||
);
|
||||
|
||||
const {
|
||||
mutate: authorizeMutation,
|
||||
onDone: onAuthorizeMutationDone,
|
||||
onError: onAuthorizeMutationError,
|
||||
} = useMutation<
|
||||
{
|
||||
authorizeApplication: {
|
||||
code: string;
|
||||
state: string;
|
||||
clientId: string;
|
||||
scope: string;
|
||||
};
|
||||
},
|
||||
{
|
||||
applicationClientId: string;
|
||||
redirectURI: string;
|
||||
state?: string | null;
|
||||
scope?: string | null;
|
||||
}
|
||||
>(AUTORIZE_APPLICATION);
|
||||
|
||||
const authorize = () => {
|
||||
authorizeMutation({
|
||||
applicationClientId: props.authApplication.clientId,
|
||||
redirectURI: props.redirectURI as string,
|
||||
state: props.state,
|
||||
scope: props.scope,
|
||||
});
|
||||
};
|
||||
|
||||
const {
|
||||
mutate: authorizeDeviceMutation,
|
||||
onDone: onAuthorizeDeviceMutationDone,
|
||||
} = useMutation<
|
||||
{
|
||||
authorizeDeviceApplication: {
|
||||
clientId: string;
|
||||
scope: string;
|
||||
};
|
||||
},
|
||||
{
|
||||
applicationClientId: string;
|
||||
userCode: string;
|
||||
}
|
||||
>(AUTORIZE_DEVICE_APPLICATION);
|
||||
|
||||
const authorizeDevice = () => {
|
||||
authorizeDeviceMutation({
|
||||
applicationClientId: props.authApplication.clientId,
|
||||
userCode: props.userCode ?? "",
|
||||
});
|
||||
};
|
||||
|
||||
onAuthorizeDeviceMutationDone(({ data }) => {
|
||||
const localClientId = data?.authorizeDeviceApplication?.clientId;
|
||||
const localScope = data?.authorizeDeviceApplication?.scope;
|
||||
|
||||
if (!localClientId || !localScope) return;
|
||||
checkDevice.value = true;
|
||||
});
|
||||
|
||||
onAuthorizeMutationDone(({ data }) => {
|
||||
const code = data?.authorizeApplication?.code;
|
||||
const localClientId = data?.authorizeApplication?.clientId;
|
||||
const localScope = data?.authorizeApplication?.scope;
|
||||
const returnedState = data?.authorizeApplication?.state ?? "";
|
||||
|
||||
if (!code || !localClientId || !localScope) return;
|
||||
|
||||
if (props.redirectURI === "urn:ietf:wg:oauth:2.0:oob") {
|
||||
checkDevice.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.redirectURI) {
|
||||
const params = new URLSearchParams(
|
||||
Object.entries({
|
||||
code,
|
||||
state: returnedState,
|
||||
client_id: localClientId,
|
||||
scope: localScope,
|
||||
})
|
||||
);
|
||||
window.location.assign(
|
||||
new URL(`${props.redirectURI}?${params.toString()}`)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const notifier = inject<Notifier>("notifier");
|
||||
|
||||
onAuthorizeMutationError(({ graphQLErrors }) => {
|
||||
graphQLErrors.forEach(({ message }) => {
|
||||
notifier?.error(message);
|
||||
});
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: computed(() => t("Authorize application")),
|
||||
});
|
||||
</script>
|
||||
291
src/components/OAuth/scopes.ts
Normal file
291
src/components/OAuth/scopes.ts
Normal file
@@ -0,0 +1,291 @@
|
||||
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, 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"),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:event:update": {
|
||||
title: t("Update events"),
|
||||
text: t("This application will be allowed to update events"),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:event:delete": {
|
||||
title: t("Delete events"),
|
||||
text: t("This application will be allowed to delete events"),
|
||||
icon: "calendar",
|
||||
},
|
||||
"write:media:upload": {
|
||||
title: t("Upload media"),
|
||||
text: t("This application will be allowed to upload media"),
|
||||
icon: "image",
|
||||
},
|
||||
"write:media:remove": {
|
||||
title: t("Remove uploaded media"),
|
||||
text: t("This application will be allowed to remove uploaded media"),
|
||||
icon: "image",
|
||||
},
|
||||
"write:group:post:create": {
|
||||
title: t("Publish group posts"),
|
||||
text: t("This application will be allowed to publish group posts"),
|
||||
icon: "bullhorn",
|
||||
},
|
||||
"write:group:post:update": {
|
||||
title: t("Update group posts"),
|
||||
text: t("This application will be allowed to update group posts"),
|
||||
icon: "bullhorn",
|
||||
},
|
||||
"write:group:post:delete": {
|
||||
title: t("Delete group posts"),
|
||||
text: t("This application will be allowed to delete group posts"),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
icon: "chat",
|
||||
},
|
||||
"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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
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"
|
||||
),
|
||||
icon: "checkbox-marked",
|
||||
},
|
||||
"write:group:group_membership": {
|
||||
title: t("Manage group memberships"),
|
||||
text: t("This application will be allowed to join and leave groups"),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:group:members": {
|
||||
title: t("Manage group members"),
|
||||
text: t(
|
||||
"This application will be allowed to list group members in all of the groups you're a member of"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:user:media": {
|
||||
title: t("Read user media"),
|
||||
text: t(
|
||||
"This application will be allowed to list the media you've uploaded"
|
||||
),
|
||||
icon: "image",
|
||||
},
|
||||
"read:user:settings": {
|
||||
title: t("Read user settings"),
|
||||
text: t("This application will be allowed to access your user settings"),
|
||||
icon: "cog",
|
||||
},
|
||||
"read:user:activity_settings": {
|
||||
title: t("Read user activity settings"),
|
||||
text: t(
|
||||
"This application will be allowed to access your user activity settings"
|
||||
),
|
||||
icon: "cog",
|
||||
},
|
||||
"read:user:participations": {
|
||||
title: t("Read user participations"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view the events you're participating to"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:user:memberships": {
|
||||
title: t("Read user memberships"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view the groups you're a member of"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"read:user:draft_events": {
|
||||
title: t("Access drafts events"),
|
||||
text: t(
|
||||
"This application will be allowed to list and view your draft events"
|
||||
),
|
||||
icon: "calendar",
|
||||
},
|
||||
"read:user:group_suggested_events": {
|
||||
title: t("Access group suggested events"),
|
||||
text: t(
|
||||
"This application will be allowed to list your suggested group events"
|
||||
),
|
||||
icon: "calendar",
|
||||
},
|
||||
"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 group 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"
|
||||
),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:profile:update": {
|
||||
title: t("Update profiles"),
|
||||
text: t("This application will be allowed to update your profiles"),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:profile:delete": {
|
||||
title: t("Delete profiles"),
|
||||
text: t("This application will be allowed to delete your profiles"),
|
||||
icon: "account-circle",
|
||||
},
|
||||
"write:comment:create": {
|
||||
title: t("Post comments"),
|
||||
text: t("This application will be allowed to post comments"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:comment:update": {
|
||||
title: t("Update comments"),
|
||||
text: t("This application will be allowed to update comments"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:comment:delete": {
|
||||
title: t("Delete comments"),
|
||||
text: t("This application will be allowed to delete comments"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:create": {
|
||||
title: t("Create group discussions"),
|
||||
text: t("This application will be allowed to create group discussions"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:update": {
|
||||
title: t("Update group discussions"),
|
||||
text: t("This application will be allowed to update group discussions"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:group:discussion:delete": {
|
||||
title: t("Delete group discussions"),
|
||||
text: t("This application will be allowed to delete group discussions"),
|
||||
icon: "comment",
|
||||
},
|
||||
"write:profile:feed_token:create": {
|
||||
title: t("Create feed tokens"),
|
||||
text: t("This application will be allowed to create feed tokens"),
|
||||
icon: "rss",
|
||||
},
|
||||
"write:feed_token:delete": {
|
||||
title: t("Delete feed tokens"),
|
||||
text: t("This application will be allowed to delete feed tokens"),
|
||||
icon: "rss",
|
||||
},
|
||||
"write:participation": {
|
||||
title: t("Manage event participations"),
|
||||
text: t("This application will be allowed to manage events participations"),
|
||||
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",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user