Client - authorize oauth client
This commit is contained in:
parent
d8d88cda3a
commit
4be4f46c26
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="new-oauth2-app">
|
<div id="new-oauth2-app">
|
||||||
<p id="new-oauth2-title">{{ $t('oauth2.ADD_A_NEW_APP') }}</p>
|
<h1 id="new-oauth2-title">{{ $t('oauth2.ADD_A_NEW_APP') }}</h1>
|
||||||
<div id="apps-form">
|
<div id="apps-form">
|
||||||
<form @submit.prevent="createApp">
|
<form @submit.prevent="createApp">
|
||||||
<div class="form-items">
|
<div class="form-items">
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div id="authorize-oauth2-app" v-if="client.client_id">
|
||||||
|
<h1 id="authorize-oauth2-title">
|
||||||
|
<i18n-t keypath="oauth2.AUTHORIZE_APP">
|
||||||
|
<router-link :to="{ name: 'UserApp', params: { id: client.id } }">
|
||||||
|
{{ client.name }}
|
||||||
|
</router-link>
|
||||||
|
</i18n-t>
|
||||||
|
</h1>
|
||||||
|
<ErrorMessage :message="errorMessages" v-if="errorMessages" />
|
||||||
|
<div class="oauth2-access">
|
||||||
|
<p>{{ $t('oauth2.APP_REQUESTING_ACCESS') }}</p>
|
||||||
|
<ul>
|
||||||
|
<li
|
||||||
|
class="client-scope"
|
||||||
|
v-for="scope in client.scope.split(' ')"
|
||||||
|
:key="scope"
|
||||||
|
>
|
||||||
|
{{ $t(`oauth2.APP.SCOPE.${scope.toUpperCase()}`) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="authorize-oauth2-buttons">
|
||||||
|
<button class="danger" @click="authorizeApp">
|
||||||
|
{{ $t('buttons.AUTHORIZE') }}
|
||||||
|
</button>
|
||||||
|
<button class="cancel" @click="$router.push('/profile/apps')">
|
||||||
|
{{ $t('buttons.CANCEL') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ComputedRef, onBeforeMount } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
||||||
|
import { IOAuth2Client } from '@/types/oauth'
|
||||||
|
import { useStore } from '@/use/useStore'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
const client: ComputedRef<IOAuth2Client> = computed(
|
||||||
|
() => store.getters[OAUTH2_STORE.GETTERS.CLIENT]
|
||||||
|
)
|
||||||
|
const errorMessages: ComputedRef<string | string[] | null> = computed(
|
||||||
|
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
|
||||||
|
)
|
||||||
|
|
||||||
|
onBeforeMount(() => loadApp())
|
||||||
|
|
||||||
|
function loadApp() {
|
||||||
|
if (route.query.client_id && typeof route.query.client_id === 'string') {
|
||||||
|
store.dispatch(
|
||||||
|
OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_CLIENT_ID,
|
||||||
|
route.query.client_id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function authorizeApp() {
|
||||||
|
store.dispatch(OAUTH2_STORE.ACTIONS.AUTHORIZE_CLIENT, {
|
||||||
|
client_id: `${route.query.client_id}`,
|
||||||
|
redirect_uri: `${route.query.redirect_uri}`,
|
||||||
|
response_type: `${route.query.response_type}`,
|
||||||
|
scope: `${route.query.scope}`,
|
||||||
|
state: `${route.query.state}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '~@/scss/vars.scss';
|
||||||
|
|
||||||
|
#authorize-oauth2-app {
|
||||||
|
#authorize-oauth2-title {
|
||||||
|
font-size: 1.05em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 $default-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth2-access {
|
||||||
|
padding: 0 $default-padding;
|
||||||
|
}
|
||||||
|
.authorize-oauth2-buttons {
|
||||||
|
display: flex;
|
||||||
|
button {
|
||||||
|
margin: $default-padding * 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -44,7 +44,15 @@
|
|||||||
{{ client.redirect_uris.length > 0 ? client.redirect_uris[0] : '' }}
|
{{ client.redirect_uris.length > 0 ? client.redirect_uris[0] : '' }}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>{{ $t('oauth2.APP.SCOPE.LABEL') }}:</dt>
|
<dt>{{ $t('oauth2.APP.SCOPE.LABEL') }}:</dt>
|
||||||
<dd>{{ client.scope }}</dd>
|
<dd>
|
||||||
|
<span
|
||||||
|
class="client-scope"
|
||||||
|
v-for="scope in client.scope.split(' ')"
|
||||||
|
:key="scope"
|
||||||
|
>
|
||||||
|
{{ $t(`oauth2.APP.SCOPE.${scope.toUpperCase()}`) }}
|
||||||
|
</span>
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<div class="app-buttons">
|
<div class="app-buttons">
|
||||||
<button class="danger" @click="updateDisplayModal(true)">
|
<button class="danger" @click="updateDisplayModal(true)">
|
||||||
@ -135,6 +143,9 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: $default-padding;
|
gap: $default-padding;
|
||||||
}
|
}
|
||||||
|
.client-scope {
|
||||||
|
padding-right: $default-padding * 0.5;
|
||||||
|
}
|
||||||
.no-description {
|
.no-description {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ACCOUNT-CONFIRMATION-RESEND": "Resend confirmation email",
|
"ACCOUNT-CONFIRMATION-RESEND": "Resend confirmation email",
|
||||||
|
"AUTHORIZE": "Authorize",
|
||||||
"BACK": "Back",
|
"BACK": "Back",
|
||||||
"CANCEL": "Cancel",
|
"CANCEL": "Cancel",
|
||||||
"CLEAR_FILTER": "Clear filters",
|
"CLEAR_FILTER": "Clear filters",
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
},
|
},
|
||||||
"APP_DELETION_CONFIRMATION": "Are you sure you want to delete this app?",
|
"APP_DELETION_CONFIRMATION": "Are you sure you want to delete this app?",
|
||||||
"APP_CREATED_SUCCESSFULLY": "Application created successfully. Make sure to copy the secret now, it won't show up again.",
|
"APP_CREATED_SUCCESSFULLY": "Application created successfully. Make sure to copy the secret now, it won't show up again.",
|
||||||
|
"APP_REQUESTING_ACCESS": "The application {0} is requesting:",
|
||||||
"APPS_LIST": "OAuth2 applications",
|
"APPS_LIST": "OAuth2 applications",
|
||||||
|
"AUTHORIZE_APP": "Authorize {0} to use your account?",
|
||||||
"DELETE_APP": "Delete application",
|
"DELETE_APP": "Delete application",
|
||||||
"NEW_APP": "New OAuth App",
|
"NEW_APP": "New OAuth App",
|
||||||
"NO_DESCRIPTION": "no description",
|
"NO_DESCRIPTION": "no description",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ACCOUNT-CONFIRMATION-RESEND": "Envoyer à nouveau l'email de confirmation",
|
"ACCOUNT-CONFIRMATION-RESEND": "Envoyer à nouveau l'email de confirmation",
|
||||||
|
"AUTHORIZE": "Autoriser",
|
||||||
"BACK": "Précédent",
|
"BACK": "Précédent",
|
||||||
"CANCEL": "Annuler",
|
"CANCEL": "Annuler",
|
||||||
"CLEAR_FILTER": "Réinitialiser",
|
"CLEAR_FILTER": "Réinitialiser",
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
},
|
},
|
||||||
"APP_DELETION_CONFIRMATION": "Êtes-vous sûr de vouloir supprimer cette application ?",
|
"APP_DELETION_CONFIRMATION": "Êtes-vous sûr de vouloir supprimer cette application ?",
|
||||||
"APP_CREATED_SUCCESSFULLY": "Application créée avec succès. Assurez-vous de copier le secret maintenant, il ne s'affichera plus.",
|
"APP_CREATED_SUCCESSFULLY": "Application créée avec succès. Assurez-vous de copier le secret maintenant, il ne s'affichera plus.",
|
||||||
|
"APP_REQUESTING_ACCESS": "L'application {0} demande les accès suivants :",
|
||||||
"APPS_LIST": "Applications OAuth2",
|
"APPS_LIST": "Applications OAuth2",
|
||||||
|
"AUTHORIZE_APP": "Autoriser {0} à utiliser votre compte ?",
|
||||||
"DELETE_APP": "Supprimer l'application",
|
"DELETE_APP": "Supprimer l'application",
|
||||||
"NEW_APP": "Ajouter une App OAuth",
|
"NEW_APP": "Ajouter une App OAuth",
|
||||||
"NO_DESCRIPTION": "pas de description",
|
"NO_DESCRIPTION": "pas de description",
|
||||||
|
@ -13,6 +13,7 @@ import UserInfosEdition from '@/components/User/ProfileEdition/UserInfosEdition.
|
|||||||
import UserPictureEdition from '@/components/User/ProfileEdition/UserPictureEdition.vue'
|
import UserPictureEdition from '@/components/User/ProfileEdition/UserPictureEdition.vue'
|
||||||
import UserPreferencesEdition from '@/components/User/ProfileEdition/UserPreferencesEdition.vue'
|
import UserPreferencesEdition from '@/components/User/ProfileEdition/UserPreferencesEdition.vue'
|
||||||
import AddUserApp from '@/components/User/UserApps/AddUserApp.vue'
|
import AddUserApp from '@/components/User/UserApps/AddUserApp.vue'
|
||||||
|
import AuthorizeUserApp from '@/components/User/UserApps/AuthorizeUserApp.vue'
|
||||||
import UserApps from '@/components/User/UserApps/index.vue'
|
import UserApps from '@/components/User/UserApps/index.vue'
|
||||||
import UserApp from '@/components/User/UserApps/UserApp.vue'
|
import UserApp from '@/components/User/UserApps/UserApp.vue'
|
||||||
import UserAppsList from '@/components/User/UserApps/UserAppsList.vue'
|
import UserAppsList from '@/components/User/UserApps/UserAppsList.vue'
|
||||||
@ -174,6 +175,11 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: 'AddUserApp',
|
name: 'AddUserApp',
|
||||||
component: AddUserApp,
|
component: AddUserApp,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'authorize',
|
||||||
|
name: 'AuthorizeUserApp',
|
||||||
|
component: AuthorizeUserApp,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -5,10 +5,60 @@ import router from '@/router'
|
|||||||
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
||||||
import { IOAuth2Actions, IOAuth2State } from '@/store/modules/oauth2/types'
|
import { IOAuth2Actions, IOAuth2State } from '@/store/modules/oauth2/types'
|
||||||
import { IRootState } from '@/store/modules/root/types'
|
import { IRootState } from '@/store/modules/root/types'
|
||||||
import { IOauth2ClientsPayload, IOAuth2ClientPayload } from '@/types/oauth'
|
import {
|
||||||
|
IOauth2ClientsPayload,
|
||||||
|
IOAuth2ClientPayload,
|
||||||
|
IOAuth2ClientAuthorizePayload,
|
||||||
|
} from '@/types/oauth'
|
||||||
import { handleError } from '@/utils'
|
import { handleError } from '@/utils'
|
||||||
|
|
||||||
|
const get_client = (
|
||||||
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
url: string
|
||||||
|
) => {
|
||||||
|
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||||
|
authApi
|
||||||
|
.get(url)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.data.status === 'success') {
|
||||||
|
context.commit(OAUTH2_STORE.MUTATIONS.SET_CLIENT, res.data.data.client)
|
||||||
|
} else {
|
||||||
|
handleError(context, null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => handleError(context, error))
|
||||||
|
}
|
||||||
|
|
||||||
export const actions: ActionTree<IOAuth2State, IRootState> & IOAuth2Actions = {
|
export const actions: ActionTree<IOAuth2State, IRootState> & IOAuth2Actions = {
|
||||||
|
[OAUTH2_STORE.ACTIONS.AUTHORIZE_CLIENT](
|
||||||
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
payload: IOAuth2ClientAuthorizePayload
|
||||||
|
): void {
|
||||||
|
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||||
|
const form = new FormData()
|
||||||
|
form.set('client_id', payload.client_id)
|
||||||
|
form.set('response_type', payload.response_type)
|
||||||
|
form.set('scope', payload.scope)
|
||||||
|
form.set('confirm', 'true')
|
||||||
|
if (payload.state) {
|
||||||
|
form.set('state', payload.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
authApi
|
||||||
|
.post('oauth/authorize', form, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status == 200 && res.data.redirect_url) {
|
||||||
|
window.location.href = res.data.redirect_url
|
||||||
|
} else {
|
||||||
|
handleError(context, null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => handleError(context, error))
|
||||||
|
},
|
||||||
[OAUTH2_STORE.ACTIONS.CREATE_CLIENT](
|
[OAUTH2_STORE.ACTIONS.CREATE_CLIENT](
|
||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
payload: IOAuth2ClientPayload
|
payload: IOAuth2ClientPayload
|
||||||
@ -47,24 +97,17 @@ export const actions: ActionTree<IOAuth2State, IRootState> & IOAuth2Actions = {
|
|||||||
})
|
})
|
||||||
.catch((error) => handleError(context, error))
|
.catch((error) => handleError(context, error))
|
||||||
},
|
},
|
||||||
|
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_CLIENT_ID](
|
||||||
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
client_id: string
|
||||||
|
): void {
|
||||||
|
get_client(context, `oauth/apps/${client_id}`)
|
||||||
|
},
|
||||||
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_ID](
|
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_ID](
|
||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
id: number
|
id: number
|
||||||
): void {
|
): void {
|
||||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
get_client(context, `oauth/apps/${id}/by_id`)
|
||||||
authApi
|
|
||||||
.get(`oauth/apps/${id}/by_id`)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data.status === 'success') {
|
|
||||||
context.commit(
|
|
||||||
OAUTH2_STORE.MUTATIONS.SET_CLIENT,
|
|
||||||
res.data.data.client
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
handleError(context, null)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => handleError(context, error))
|
|
||||||
},
|
},
|
||||||
[OAUTH2_STORE.ACTIONS.GET_CLIENTS](
|
[OAUTH2_STORE.ACTIONS.GET_CLIENTS](
|
||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
export enum OAuth2Actions {
|
export enum OAuth2Actions {
|
||||||
|
AUTHORIZE_CLIENT = 'AUTHORIZE_CLIENT',
|
||||||
CREATE_CLIENT = 'CREATE_CLIENT',
|
CREATE_CLIENT = 'CREATE_CLIENT',
|
||||||
DELETE_CLIENT = 'DELETE_CLIENT',
|
DELETE_CLIENT = 'DELETE_CLIENT',
|
||||||
GET_CLIENTS = 'GET_CLIENTS',
|
GET_CLIENTS = 'GET_CLIENTS',
|
||||||
|
GET_CLIENT_BY_CLIENT_ID = 'GET_CLIENT_BY_CLIENT_ID',
|
||||||
GET_CLIENT_BY_ID = 'GET_CLIENT_BY_ID',
|
GET_CLIENT_BY_ID = 'GET_CLIENT_BY_ID',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import { IRootState } from '@/store/modules/root/types'
|
|||||||
import { IPagination } from '@/types/api'
|
import { IPagination } from '@/types/api'
|
||||||
import {
|
import {
|
||||||
IOAuth2Client,
|
IOAuth2Client,
|
||||||
|
IOAuth2ClientAuthorizePayload,
|
||||||
IOAuth2ClientPayload,
|
IOAuth2ClientPayload,
|
||||||
IOauth2ClientsPayload,
|
IOauth2ClientsPayload,
|
||||||
} from '@/types/oauth'
|
} from '@/types/oauth'
|
||||||
@ -21,6 +22,10 @@ export interface IOAuth2State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IOAuth2Actions {
|
export interface IOAuth2Actions {
|
||||||
|
[OAUTH2_STORE.ACTIONS.AUTHORIZE_CLIENT](
|
||||||
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
payload: IOAuth2ClientAuthorizePayload
|
||||||
|
): void
|
||||||
[OAUTH2_STORE.ACTIONS.CREATE_CLIENT](
|
[OAUTH2_STORE.ACTIONS.CREATE_CLIENT](
|
||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
payload: IOAuth2ClientPayload
|
payload: IOAuth2ClientPayload
|
||||||
@ -29,6 +34,10 @@ export interface IOAuth2Actions {
|
|||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
id: number
|
id: number
|
||||||
): void
|
): void
|
||||||
|
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_CLIENT_ID](
|
||||||
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
|
client_id: string
|
||||||
|
): void
|
||||||
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_ID](
|
[OAUTH2_STORE.ACTIONS.GET_CLIENT_BY_ID](
|
||||||
context: ActionContext<IOAuth2State, IRootState>,
|
context: ActionContext<IOAuth2State, IRootState>,
|
||||||
id: number
|
id: number
|
||||||
|
@ -21,3 +21,11 @@ export interface IOAuth2ClientPayload {
|
|||||||
export interface IOauth2ClientsPayload {
|
export interface IOauth2ClientsPayload {
|
||||||
page?: number
|
page?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IOAuth2ClientAuthorizePayload {
|
||||||
|
client_id: string
|
||||||
|
redirect_uri: string
|
||||||
|
response_type: string
|
||||||
|
scope: string
|
||||||
|
state?: string
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user