Adding permanently delete account comments and posts.

- Fixes #285
- Fixes #58
This commit is contained in:
Dessalines 2019-10-15 15:09:01 -07:00
parent 272ab3948c
commit 3e16882f8c
7 changed files with 117 additions and 2 deletions

View file

@ -56,6 +56,7 @@ pub enum UserOperation {
SaveUserSettings, SaveUserSettings,
TransferCommunity, TransferCommunity,
TransferSite, TransferSite,
DeleteAccount,
} }
#[derive(Fail, Debug)] #[derive(Fail, Debug)]

View file

@ -103,6 +103,11 @@ pub struct GetReplies {
auth: String, auth: String,
} }
#[derive(Serialize, Deserialize)]
pub struct DeleteAccount {
auth: String,
}
impl Perform<LoginResponse> for Oper<Login> { impl Perform<LoginResponse> for Oper<Login> {
fn perform(&self) -> Result<LoginResponse, Error> { fn perform(&self) -> Result<LoginResponse, Error> {
let data: &Login = &self.data; let data: &Login = &self.data;
@ -583,3 +588,67 @@ impl Perform<GetRepliesResponse> for Oper<MarkAllAsRead> {
}) })
} }
} }
impl Perform<LoginResponse> for Oper<DeleteAccount> {
fn perform(&self) -> Result<LoginResponse, Error> {
let data: &DeleteAccount = &self.data;
let conn = establish_connection();
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
};
let user_id = claims.id;
// Comments
let comments = CommentView::list(&conn, &SortType::New, None, Some(user_id), None, None, false, None, Some(std::i64::MAX))?;
for comment in &comments {
let comment_form = CommentForm {
content: "*Permananently Deleted*".to_string(),
parent_id: comment.to_owned().parent_id,
post_id: comment.to_owned().post_id,
creator_id: comment.to_owned().creator_id,
removed: None,
deleted: Some(true),
read: None,
updated: Some(naive_now()),
};
let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) {
Ok(comment) => comment,
Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment"))?,
};
}
// Posts
let posts = PostView::list(&conn, PostListingType::All, &SortType::New,None, Some(user_id), None, None, None, true, false, false, None, Some(std::i64::MAX))?;
for post in &posts {
let post_form = PostForm {
name: "*Permananently Deleted*".to_string(),
url: Some("https://deleted.com".to_string()),
body: Some("*Permananently Deleted*".to_string()),
creator_id: post.to_owned().creator_id,
community_id: post.to_owned().community_id,
removed: None,
deleted: Some(true),
nsfw: post.to_owned().nsfw,
locked: None,
stickied: None,
updated: Some(naive_now()),
};
let _updated_post = match Post::update(&conn, post.id, &post_form) {
Ok(post) => post,
Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_post"))?,
};
}
Ok(LoginResponse {
op: self.op.to_string(),
jwt: data.auth.to_owned(),
})
}
}

View file

@ -519,5 +519,10 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result<Str
let res = Oper::new(user_operation, transfer_site).perform()?; let res = Oper::new(user_operation, transfer_site).perform()?;
Ok(serde_json::to_string(&res)?) Ok(serde_json::to_string(&res)?)
} }
UserOperation::DeleteAccount => {
let delete_account: DeleteAccount = serde_json::from_str(data)?;
let res = Oper::new(user_operation, delete_account).perform()?;
Ok(serde_json::to_string(&res)?)
}
} }
} }

View file

@ -31,6 +31,8 @@ interface UserState {
loading: boolean; loading: boolean;
userSettingsForm: UserSettingsForm; userSettingsForm: UserSettingsForm;
userSettingsLoading: boolean; userSettingsLoading: boolean;
deleteAccountLoading: boolean;
deleteAccountShowConfirm: boolean;
} }
export class User extends Component<any, UserState> { export class User extends Component<any, UserState> {
@ -65,6 +67,8 @@ export class User extends Component<any, UserState> {
auth: null, auth: null,
}, },
userSettingsLoading: null, userSettingsLoading: null,
deleteAccountLoading: null,
deleteAccountShowConfirm: false,
} }
constructor(props: any, context: any) { constructor(props: any, context: any) {
@ -307,8 +311,17 @@ export class User extends Component<any, UserState> {
</div> </div>
<div class="form-group row mb-0"> <div class="form-group row mb-0">
<div class="col-12"> <div class="col-12">
<button type="submit" class="btn btn-secondary">{this.state.userSettingsLoading ? <button type="submit" class="btn btn-secondary mr-4">{this.state.userSettingsLoading ?
<svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> : capitalizeFirstLetter(i18n.t('save'))}</button> <svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> : capitalizeFirstLetter(i18n.t('save'))}</button>
<button class="btn btn-danger" onClick={linkEvent(this, this.handleDeleteAccountShowConfirmToggle)}><T i18nKey="delete_account">#</T></button>
{this.state.deleteAccountShowConfirm &&
<>
<div class="mt-2 alert alert-danger" role="alert"><T i18nKey="delete_account_confirm">#</T></div>
<button class="btn btn-danger mr-4" onClick={linkEvent(this, this.handleDeleteAccount)}>{this.state.deleteAccountLoading ?
<svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> : capitalizeFirstLetter(i18n.t('yes'))}</button>
<button class="btn btn-secondary" onClick={linkEvent(this, this.handleDeleteAccountShowConfirmToggle)}><T i18nKey="cancel">#</T></button>
</>
}
</div> </div>
</div> </div>
</form> </form>
@ -434,6 +447,20 @@ export class User extends Component<any, UserState> {
WebSocketService.Instance.saveUserSettings(i.state.userSettingsForm); WebSocketService.Instance.saveUserSettings(i.state.userSettingsForm);
} }
handleDeleteAccountShowConfirmToggle(i: User, event: any) {
event.preventDefault();
i.state.deleteAccountShowConfirm = !i.state.deleteAccountShowConfirm;
i.setState(i.state);
}
handleDeleteAccount(i: User, event: any) {
event.preventDefault();
i.state.deleteAccountLoading = true;
i.setState(i.state);
WebSocketService.Instance.deleteAccount();
}
parseMessage(msg: any) { parseMessage(msg: any) {
console.log(msg); console.log(msg);
let op: UserOperation = msgOp(msg); let op: UserOperation = msgOp(msg);
@ -505,6 +532,11 @@ export class User extends Component<any, UserState> {
this.setState(this.state); this.setState(this.state);
let res: LoginResponse = msg; let res: LoginResponse = msg;
UserService.Instance.login(res); UserService.Instance.login(res);
} else if (op == UserOperation.DeleteAccount) {
this.state.deleteAccountLoading = false;
this.state.deleteAccountShowConfirm = false;
this.setState(this.state);
this.context.router.history.push('/');
} }
} }
} }

View file

@ -1,5 +1,5 @@
export enum UserOperation { export enum UserOperation {
Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead, SaveUserSettings, TransferCommunity, TransferSite Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead, SaveUserSettings, TransferCommunity, TransferSite, DeleteAccount
} }
export enum CommentSortType { export enum CommentSortType {

View file

@ -199,6 +199,12 @@ export class WebSocketService {
this.subject.next(this.wsSendWrapper(UserOperation.SaveUserSettings, userSettingsForm)); this.subject.next(this.wsSendWrapper(UserOperation.SaveUserSettings, userSettingsForm));
} }
public deleteAccount() {
let form = {};
this.setAuth(form);
this.subject.next(this.wsSendWrapper(UserOperation.DeleteAccount, form));
}
private wsSendWrapper(op: UserOperation, data: any) { private wsSendWrapper(op: UserOperation, data: any) {
let send = { op: UserOperation[op], data: data }; let send = { op: UserOperation[op], data: data };
console.log(send); console.log(send);

View file

@ -55,6 +55,8 @@ export const en = {
mark_as_unread: 'mark as unread', mark_as_unread: 'mark as unread',
delete: 'delete', delete: 'delete',
deleted: 'deleted', deleted: 'deleted',
delete_account: 'Delete Account',
delete_account_confirm: 'Warning: this will permanently delete all your data. Are you sure?',
restore: 'restore', restore: 'restore',
ban: 'ban', ban: 'ban',
ban_from_site: 'ban from site', ban_from_site: 'ban from site',