Implemented api key deletion
This commit is contained in:
@ -6,6 +6,7 @@ import { Input, ButtonOutline, InlineForm } from 'rebass';
|
||||
import Layout, { Title } from 'components/Layout';
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import SlackAuthLink from 'components/SlackAuthLink';
|
||||
import ApiKeyRow from './components/ApiKeyRow';
|
||||
|
||||
import styles from './Settings.scss';
|
||||
|
||||
@ -65,13 +66,12 @@ class Settings extends React.Component {
|
||||
{ this.store.apiKeys && (
|
||||
<table className={ styles.apiKeyTable }>
|
||||
{ this.store.apiKeys.map(key => (
|
||||
<tr>
|
||||
<td>{ key.name }</td>
|
||||
<td><code>{ key.secret }</code></td>
|
||||
{/* <td>
|
||||
<span className={ styles.deleteAction }>Delete</span>
|
||||
</td> */}
|
||||
</tr>
|
||||
<ApiKeyRow
|
||||
id={ key.id }
|
||||
name={ key.name }
|
||||
secret={ key.secret }
|
||||
onDelete={ this.store.deleteApiKey }
|
||||
/>
|
||||
)) }
|
||||
</table>
|
||||
) }
|
||||
|
@ -17,9 +17,3 @@
|
||||
color: #969696;
|
||||
}
|
||||
}
|
||||
|
||||
.deleteAction {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: $textColor;
|
||||
}
|
||||
|
@ -40,6 +40,22 @@ class SearchStore {
|
||||
this.isFetching = false;
|
||||
}
|
||||
|
||||
@action deleteApiKey = async (id) => {
|
||||
this.isFetching = true;
|
||||
|
||||
try {
|
||||
await client.post('/apiKeys.delete', {
|
||||
id,
|
||||
});
|
||||
runInAction('deleteApiKey', () => {
|
||||
this.fetchApiKeys();
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Something went wrong");
|
||||
}
|
||||
this.isFetching = false;
|
||||
}
|
||||
|
||||
@action setKeyName = (value) => {
|
||||
this.keyName = value.target.value;
|
||||
}
|
||||
|
50
frontend/scenes/Settings/components/ApiKeyRow/ApiKeyRow.js
Normal file
50
frontend/scenes/Settings/components/ApiKeyRow/ApiKeyRow.js
Normal file
@ -0,0 +1,50 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
import styles from './ApiKeyRow.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
class ApiKeyRow extends React.Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
secret: PropTypes.string.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
state = {
|
||||
disabled: false,
|
||||
}
|
||||
|
||||
onClick = () => {
|
||||
this.props.onDelete(this.props.id);
|
||||
this.setState({ disabled: true });
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
name,
|
||||
secret,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
disabled,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>{ name }</td>
|
||||
<td><code>{ secret }</code></td>
|
||||
<td>
|
||||
<span
|
||||
role="button"
|
||||
onClick={ this.onClick }
|
||||
className={ cx(styles.deleteAction, { disabled }) }
|
||||
>Delete</span>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ApiKeyRow;
|
10
frontend/scenes/Settings/components/ApiKeyRow/ApiKeyRow.scss
Normal file
10
frontend/scenes/Settings/components/ApiKeyRow/ApiKeyRow.scss
Normal file
@ -0,0 +1,10 @@
|
||||
@import '~styles/constants.scss';
|
||||
|
||||
.deleteAction {
|
||||
font-size: 14px;
|
||||
color: $textColor;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
2
frontend/scenes/Settings/components/ApiKeyRow/index.js
Normal file
2
frontend/scenes/Settings/components/ApiKeyRow/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
import ApiKeyRow from './ApiKeyRow';
|
||||
export default ApiKeyRow;
|
@ -93,6 +93,9 @@ hr {
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #ccc;
|
||||
}
|
||||
*[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:global {
|
||||
.hljs {
|
||||
|
@ -50,4 +50,27 @@ router.post('apiKeys.list', auth(), pagination(), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post('apiKeys.delete', auth(), async (ctx) => {
|
||||
const {
|
||||
id,
|
||||
} = ctx.body;
|
||||
ctx.assertPresent(id, 'id is required');
|
||||
|
||||
const user = ctx.state.user;
|
||||
const key = await ApiKey.findById(id);
|
||||
|
||||
if (!key || key.userId !== user.id) throw httpErrors.BadRequest();
|
||||
|
||||
// Delete the actual document
|
||||
try {
|
||||
await key.destroy();
|
||||
} catch (e) {
|
||||
throw httpErrors.BadRequest('Error while deleting key');
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
success: true,
|
||||
};
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -232,7 +232,7 @@ router.post('documents.delete', auth(), async (ctx) => {
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
ok: true,
|
||||
success: true,
|
||||
};
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user