Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6af34335a8 |
@@ -38,6 +38,11 @@ class Api::V1::ProfilesController < Api::BaseController
|
||||
head :ok
|
||||
end
|
||||
|
||||
def reset_access_token
|
||||
@user.access_token.regenerate_token
|
||||
@user.reload
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
|
||||
@@ -102,4 +102,8 @@ export default {
|
||||
const urlData = endPoints('resendConfirmation');
|
||||
return axios.post(urlData.url);
|
||||
},
|
||||
resetAccessToken() {
|
||||
const urlData = endPoints('resetAccessToken');
|
||||
return axios.post(urlData.url);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -51,6 +51,9 @@ const endPoints = {
|
||||
resendConfirmation: {
|
||||
url: '/api/v1/profile/resend_confirmation',
|
||||
},
|
||||
resetAccessToken: {
|
||||
url: '/api/v1/profile/reset_access_token',
|
||||
},
|
||||
};
|
||||
|
||||
export default page => {
|
||||
|
||||
@@ -76,7 +76,10 @@
|
||||
"ACCESS_TOKEN": {
|
||||
"TITLE": "Access Token",
|
||||
"NOTE": "This token can be used if you are building an API based integration",
|
||||
"COPY": "Copy"
|
||||
"COPY": "Copy",
|
||||
"RESET": "Reset",
|
||||
"RESET_SUCCESS": "Access token regenerated",
|
||||
"RESET_ERROR": "Could not reset token"
|
||||
},
|
||||
"AUDIO_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Audio Alerts",
|
||||
|
||||
@@ -7,7 +7,7 @@ const props = defineProps({
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['onCopy']);
|
||||
const emit = defineEmits(['onCopy', 'onReset']);
|
||||
const inputType = ref('password');
|
||||
const toggleMasked = () => {
|
||||
inputType.value = inputType.value === 'password' ? 'text' : 'password';
|
||||
@@ -20,6 +20,10 @@ const maskIcon = computed(() => {
|
||||
const onClick = () => {
|
||||
emit('onCopy', props.value);
|
||||
};
|
||||
|
||||
const onReset = () => {
|
||||
emit('onReset');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -56,5 +60,15 @@ const onClick = () => {
|
||||
>
|
||||
{{ $t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.COPY') }}
|
||||
</FormButton>
|
||||
<FormButton
|
||||
type="button"
|
||||
size="large"
|
||||
icon="key"
|
||||
variant="outline"
|
||||
color-scheme="primary"
|
||||
@click="onReset"
|
||||
>
|
||||
{{ $t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.RESET') }}
|
||||
</FormButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -181,6 +181,14 @@ export default {
|
||||
await copyTextToClipboard(value);
|
||||
useAlert(this.$t('COMPONENTS.CODE.COPY_SUCCESSFUL'));
|
||||
},
|
||||
async resetAccessToken() {
|
||||
const success = await this.$store.dispatch('resetAccessToken');
|
||||
if (success) {
|
||||
useAlert(this.$t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.RESET_SUCCESS'));
|
||||
} else {
|
||||
useAlert(this.$t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.RESET_ERROR'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -281,7 +289,11 @@ export default {
|
||||
)
|
||||
"
|
||||
>
|
||||
<AccessToken :value="currentUser.access_token" @on-copy="onCopyToken" />
|
||||
<AccessToken
|
||||
:value="currentUser.access_token"
|
||||
@on-copy="onCopyToken"
|
||||
@on-reset="resetAccessToken"
|
||||
/>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -213,6 +213,16 @@ export const actions = {
|
||||
}
|
||||
},
|
||||
|
||||
resetAccessToken: async ({ commit }) => {
|
||||
try {
|
||||
const response = await authAPI.resetAccessToken();
|
||||
commit(types.SET_CURRENT_USER, response.data);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
resendConfirmation: async () => {
|
||||
try {
|
||||
await authAPI.resendConfirmation();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
json.partial! 'api/v1/models/user', formats: [:json], resource: @user
|
||||
@@ -16,16 +16,13 @@ development:
|
||||
<<: *default
|
||||
database: "<%= ENV.fetch('POSTGRES_DATABASE', 'chatwoot_dev') %>"
|
||||
username: "<%= ENV.fetch('POSTGRES_USERNAME', 'postgres') %>"
|
||||
password: "<%= ENV.fetch('POSTGRES_PASSWORD', '') %>"
|
||||
|
||||
test:
|
||||
<<: *default
|
||||
database: "<%= ENV.fetch('POSTGRES_DATABASE', 'chatwoot_test') %>"
|
||||
username: "<%= ENV.fetch('POSTGRES_USERNAME', 'postgres') %>"
|
||||
password: "<%= ENV.fetch('POSTGRES_PASSWORD', '') %>"
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
database: "<%= ENV.fetch('POSTGRES_DATABASE', 'chatwoot_production') %>"
|
||||
username: "<%= ENV.fetch('POSTGRES_USERNAME', 'chatwoot_prod') %>"
|
||||
password: "<%= ENV.fetch('POSTGRES_PASSWORD', 'chatwoot_prod') %>"
|
||||
|
||||
@@ -295,6 +295,7 @@ Rails.application.routes.draw do
|
||||
post :auto_offline
|
||||
put :set_active_account
|
||||
post :resend_confirmation
|
||||
post :reset_access_token
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -296,4 +296,32 @@ RSpec.describe 'Profile API', type: :request do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/profile/reset_access_token' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
post '/api/v1/profile/reset_access_token'
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
|
||||
it 'regenerates the access token' do
|
||||
old_token = agent.access_token.token
|
||||
|
||||
post '/api/v1/profile/reset_access_token',
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
agent.reload
|
||||
json_response = response.parsed_body
|
||||
expect(json_response['access_token']).to eq(agent.access_token.token)
|
||||
expect(agent.access_token.token).not_to eq(old_token)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user