202 lines
5.1 KiB
Vue
202 lines
5.1 KiB
Vue
<script>
|
|
import {
|
|
GlButton,
|
|
GlModalDirective,
|
|
GlTooltip,
|
|
GlModal,
|
|
GlFormGroup,
|
|
GlFormInput,
|
|
GlSprintf,
|
|
} from '@gitlab/ui';
|
|
import { s__, __, sprintf } from '~/locale';
|
|
import { REVOKE_TOKEN_MODAL_ID, TOKEN_STATUS_ACTIVE } from '../constants';
|
|
import revokeAgentToken from '../graphql/mutations/revoke_token.mutation.graphql';
|
|
import getClusterAgentQuery from '../graphql/queries/get_cluster_agent.query.graphql';
|
|
import { removeTokenFromStore } from '../graphql/cache_update';
|
|
|
|
export default {
|
|
components: {
|
|
GlButton,
|
|
GlTooltip,
|
|
GlModal,
|
|
GlFormGroup,
|
|
GlFormInput,
|
|
GlSprintf,
|
|
},
|
|
directives: {
|
|
GlModalDirective,
|
|
},
|
|
inject: ['agentName', 'projectPath', 'canAdminCluster'],
|
|
props: {
|
|
token: {
|
|
required: true,
|
|
type: Object,
|
|
validator: (value) => ['id', 'name'].every((prop) => value[prop]),
|
|
},
|
|
cursor: {
|
|
required: true,
|
|
type: Object,
|
|
},
|
|
},
|
|
i18n: {
|
|
revokeButton: s__('ClusterAgents|Revoke token'),
|
|
dropdownDisabledHint: s__(
|
|
'ClusterAgents|Requires a Maintainer or greater role to perform this action',
|
|
),
|
|
modalTitle: s__('ClusterAgents|Revoke access token?'),
|
|
modalBody: s__(
|
|
'ClusterAgents|Are you sure you want to revoke this token? You cannot undo this action.',
|
|
),
|
|
modalInputLabel: s__('ClusterAgents|To revoke the token, type %{name} to confirm:'),
|
|
modalCancel: __('Cancel'),
|
|
successMessage: s__('ClusterAgents|%{name} successfully revoked'),
|
|
defaultError: __('An error occurred. Please try again.'),
|
|
},
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
error: null,
|
|
revokeConfirmText: null,
|
|
tokenName: null,
|
|
variables: {
|
|
agentName: this.agentName,
|
|
projectPath: this.projectPath,
|
|
tokenStatus: TOKEN_STATUS_ACTIVE,
|
|
...this.cursor,
|
|
},
|
|
};
|
|
},
|
|
computed: {
|
|
revokeBtnDisabled() {
|
|
return this.loading || !this.canAdminCluster;
|
|
},
|
|
modalId() {
|
|
return sprintf(REVOKE_TOKEN_MODAL_ID, {
|
|
tokenName: this.token.name,
|
|
});
|
|
},
|
|
primaryModalProps() {
|
|
return {
|
|
text: this.$options.i18n.revokeButton,
|
|
attributes: [
|
|
{ disabled: this.loading || this.disableModalSubmit, loading: this.loading },
|
|
{ variant: 'danger' },
|
|
],
|
|
};
|
|
},
|
|
cancelModalProps() {
|
|
return {
|
|
text: this.$options.i18n.modalCancel,
|
|
attributes: [],
|
|
};
|
|
},
|
|
disableModalSubmit() {
|
|
return this.revokeConfirmText !== this.token.name;
|
|
},
|
|
},
|
|
methods: {
|
|
async revokeToken() {
|
|
if (this.disableModalSubmit || this.loading) {
|
|
return;
|
|
}
|
|
|
|
this.loading = true;
|
|
this.error = null;
|
|
this.tokenName = this.token.name;
|
|
|
|
try {
|
|
const { errors } = await this.revokeTokenMutation();
|
|
|
|
if (errors.length) {
|
|
throw new Error(errors[0]);
|
|
}
|
|
} catch (error) {
|
|
this.error = error?.message || this.$options.i18n.defaultError;
|
|
} finally {
|
|
this.loading = false;
|
|
const successMessage = sprintf(this.$options.i18n.successMessage, {
|
|
name: this.tokenName,
|
|
});
|
|
|
|
this.$toast.show(this.error || successMessage);
|
|
|
|
this.hideModal();
|
|
}
|
|
},
|
|
revokeTokenMutation() {
|
|
return this.$apollo
|
|
.mutate({
|
|
mutation: revokeAgentToken,
|
|
variables: {
|
|
input: {
|
|
id: this.token.id,
|
|
},
|
|
},
|
|
update: (store) => {
|
|
removeTokenFromStore(store, this.token, getClusterAgentQuery, this.variables);
|
|
},
|
|
})
|
|
|
|
.then(({ data: { clusterAgentTokenRevoke } }) => {
|
|
return clusterAgentTokenRevoke;
|
|
});
|
|
},
|
|
resetModal() {
|
|
this.loading = false;
|
|
this.error = null;
|
|
this.revokeConfirmText = null;
|
|
},
|
|
hideModal() {
|
|
this.resetModal();
|
|
this.$refs.modal.hide();
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div ref="revokeToken" class="gl-display-inline-block">
|
|
<gl-button
|
|
v-gl-modal-directive="modalId"
|
|
icon="remove"
|
|
category="secondary"
|
|
variant="danger"
|
|
:disabled="revokeBtnDisabled"
|
|
:title="$options.i18n.revokeButton"
|
|
:aria-label="$options.i18n.revokeButton"
|
|
/>
|
|
|
|
<gl-tooltip
|
|
v-if="!canAdminCluster"
|
|
:target="() => $refs.revokeToken"
|
|
:title="$options.i18n.dropdownDisabledHint"
|
|
/>
|
|
</div>
|
|
|
|
<gl-modal
|
|
ref="modal"
|
|
:modal-id="modalId"
|
|
:title="$options.i18n.modalTitle"
|
|
:action-primary="primaryModalProps"
|
|
:action-cancel="cancelModalProps"
|
|
size="sm"
|
|
@primary="revokeToken"
|
|
@hide="hideModal"
|
|
>
|
|
<p>{{ $options.i18n.modalBody }}</p>
|
|
|
|
<gl-form-group>
|
|
<template #label>
|
|
<gl-sprintf :message="$options.i18n.modalInputLabel">
|
|
<template #name>
|
|
<code>{{ token.name }}</code>
|
|
</template>
|
|
</gl-sprintf>
|
|
</template>
|
|
<gl-form-input v-model="revokeConfirmText" @keydown.enter="revokeToken" />
|
|
</gl-form-group>
|
|
</gl-modal>
|
|
</div>
|
|
</template>
|