adds force account rename page

This commit is contained in:
tomlum 2023-06-15 21:40:33 -04:00
parent bc9680cb6f
commit 2f7e12bd0c
4 changed files with 383 additions and 6 deletions

View file

@ -14,9 +14,11 @@ const Types = keyMirror({
const banGoodListPaths = [
'/accounts/banned-response',
'/accounts/bad-username',
'/community_guidelines',
'/privacy_policy',
'/terms_of_use'
'/terms_of_use',
'/accounts/update_username'
];
module.exports.Status = keyMirror({
@ -70,7 +72,11 @@ const handleSessionResponse = (dispatch, body) => {
body.user.banned &&
banGoodListPaths.every(goodPath => window.location.pathname.indexOf(goodPath) === -1)
) {
if(body.user.banned_status === 'far_banned'){
window.location = '/accounts/bad-username/';
} else {
window.location = '/accounts/banned-response/';
}
return;
} else if (
body.flags &&

View file

@ -424,10 +424,10 @@
"title": "micro:bit"
},
{
"name": "banned-splash",
"pattern": "^/accounts/banned-response/?(\\?.*)?$",
"routeAlias": "/accounts/banned-response/?$",
"view": "banned-splash/banned-splash",
"name": "bad-username-splash",
"pattern": "^/accounts/bad-username/?(\\?.*)?$",
"routeAlias": "/accounts/bad-username/?$",
"view": "bad-username-splash/bad-username-splash",
"title": "Account Blocked"
},
{

View file

@ -0,0 +1,246 @@
/* eslint-disable */
const injectIntl = require('react-intl').injectIntl;
// const intlShape = require('react-intl').intlShape;
// const FormattedMessage = require('react-intl').FormattedMessage;
const React = require('react');
const FormattedMessage = require('react-intl').FormattedMessage;
import {connect} from 'react-redux';
import {selectBannedUser, selectHasFetchedSession} from '../../redux/session';
const messageActions = require('../../redux/messages.js');
const JoinFlowStep = require('../../components/join-flow/join-flow-step.jsx');
const FormikInput = require('../../components/formik-forms/formik-input.jsx');
import {Formik} from 'formik';
const PropTypes = require('prop-types');
const Page = require('../../components/page/www/page.jsx');
const render = require('../../lib/render.jsx');
const api = require('../../lib/api');
import bannedIcon from './blocked-account.svg';
require('../../components/extension-landing/extension-landing.scss');
require('./bad-username-splash.scss');
const BannedSplash = ({hasSession, user, adminMessages, getAdminMessages}) => {
const [unauthorizedError, setUnauthorizedError] = React.useState(false)
const [badUsernameError, setBadUsernameError] = React.useState(false)
const [apiError, setAPIError] = React.useState(false)
React.useEffect(() => {
if (user && user.username && user.token){
getAdminMessages(user.username, user.token);
}
}, [user]);
const handleUpdateUsernameUnbanSubmit = (formData, formikBag) => {
setUnauthorizedError(false)
setBadUsernameError(false)
setAPIError(false)
formikBag.setSubmitting(false); // formik makes us do this ourselves
console.log("attempting submit!")
api({
host: '',
uri: '/accounts/update_username/',
method: 'post',
useCsrf: true,
json: {
new_username: formData.newUsername,
username: formData.username,
password: formData.password
}
}, (err, body, res) => {
if(res.body.error === "Unauthorized"){
setUnauthorizedError("error message for unauthorized access")
}
else if(res.body.error === "Invalid username"){
setBadUsernameError("error message for invalid username")
}
else if(res.body.error){
setAPIError("error message for API error")
} else{
window.location = '/';
}
});
}
if (hasSession && (!user || !user.banned)){
window.location = '/';
}
if (user && user.banned){
return (<div id="bad-username-splash">
<div id="force-account-rename">
<div id="force-account-rename-inner">
<div
id="force-account-rename-text"
className="col"
>
<span>
<img
className="banned-icon"
src={bannedIcon}
/>
<h1 className="inline"><FormattedMessage id="renameAccount.accountBlocked"/></h1>
</span>
<h3><FormattedMessage id="renameAccount.toRecover"/></h3>
<p><FormattedMessage id="renameAccount.yourScratchAccount"/></p>
<p><FormattedMessage id="renameAccount.privacyIssue"/></p>
<p><FormattedMessage id="renameAccount.thingsToAvoid"/></p>
</div>
<div className="col">
<Formik
initialValues={{
newUsername: '',
newUsernameConfirm: '',
username: user.username,
password: ''
}}
validateOnBlur={true}
validateOnChange={false}
onSubmit={handleUpdateUsernameUnbanSubmit}
>
{({
errors,
handleSubmit,
isSubmitting,
setFieldError,
setFieldTouched,
setFieldValue,
// touched,
validateField,
values
}) => {
return (
<JoinFlowStep
description={<FormattedMessage id="renameAccount.makeSure"/>}
innerClassName="change-username-inner"
outerClassName="change-username-outer"
title={<FormattedMessage id="renameAccount.changeYourUsername" values={{communityGuidelinesLink: <a href="/community_guidelines"><FormattedMessage id="renameAccount.communityGuidelines"/></a>}}/>}
waiting={isSubmitting}
onSubmit={handleSubmit}
nextButton={<FormattedMessage id="renameAccount.change"/>}
>
<div>
<FormikInput
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
error={errors.newUsername}
id="newUsername"
name="newUsername"
placeholder={'Type your new username'}
spellCheck={false}
// toolTip={this.state.focused === 'username' && !touched.username &&
// this.props.intl.formatMessage({id: 'registration.usernameAdviceShort'})}
/* eslint-disable react/jsx-no-bind */
validate={validateUsername}
validationClassName="validation-left validation-full-width-input"
/* eslint-disable react/jsx-no-bind */
onBlur={() => validateField('newUsername')}
onChange={e => {
setFieldValue('newUsername', e.target.value.substring(0, 30));
setFieldTouched('newUsername');
setFieldError('newUsername', null);
}}
/>
<FormikInput
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className={'join-flow-input'}
error={errors.newUsernameConfirm || badUsernameError}
id="newUsernameConfirm"
name="newUsernameConfirm"
placeholder={'Type your new username again'}
spellCheck={false}
validationClassName="validation-left validation-full-width-input"
onChange={e => {
setFieldValue('newUsernameConfirm', e.target.value.substring(0, 30));
setFieldTouched('newUsernameConfirm');
setFieldError('newUsernameConfirm', null);
}}
/>
<FormikInput
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className={'join-flow-input'}
id="password"
name="password"
placeholder={'Enter your password'}
spellCheck={false}
error={unauthorizedError || apiError}
validationClassName="validation-left validation-full-width-input"
onChange={e => {
setFieldValue('password', e.target.value);
setFieldTouched('password');
setFieldError('password', null);
}}
/>
</div>
</JoinFlowStep>);
}}
</Formik>
</div>
</div>
</div>
<div id="admin-message-list">
<div id="admin-message-list-title">
<b><FormattedMessage id="renameAccount.pastNotifications"/></b>
</div>
{adminMessages.map(message => (
<div
className="admin-message"
key={message.id}
>
<div className="admin-message-date">
{new Date(message.datetime_created).toDateString()}
</div>
{/* // eslint-disable-next-line react/no-danger */}
<div dangerouslySetInnerHTML={{__html: message.message}} />
</div>
))}
</div>
</div>
);
}
return <div />;
};
BannedSplash.propTypes = {
user: PropTypes.shape({
username: PropTypes.string,
banned: PropTypes.bool,
token: PropTypes.string
}),
hasSession: PropTypes.bool,
adminMessages: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number.isRequired,
datetimeCreated: PropTypes.string.isRequired,
message: PropTypes.string.isRequired
})),
getAdminMessages: PropTypes.func
};
const ConnectedBannedSplash = connect(
state => ({
user: selectBannedUser(state),
hasSession: selectHasFetchedSession(state),
adminMessages: state.messages.messages && state.messages.messages.admin
}),
dispatch => ({
getAdminMessages: (username, token) => {
dispatch(messageActions.getAdminMessages(
username, token, 0
));
}
})
)(BannedSplash);
const WrappedBannedSplash = injectIntl(ConnectedBannedSplash);
render(<Page><WrappedBannedSplash /></Page>, document.getElementById('app'),
{messages: messageActions.messagesReducer});

View file

@ -0,0 +1,125 @@
@import "../../colors";
@import "../../frameless";
.validation-left {
transform: translate(-20.5rem, 0);
}
@media #{$intermediate-and-smaller} {
.validation-full-width-input {
box-sizing: border-box;
transform: unset;
margin-bottom: .75rem;
max-width: 100%;
}
}
.inline{
display:inline;
}
#bad-username-splash{
display: flex;
flex-direction: column;
align-items: center;
}
#force-account-rename{
width: 100%;
display: flex;
justify-content: center;
#force-account-rename-inner{
max-width: 1094px;
display: flex;
flex-direction: row;
@media only screen and (max-width: 800px) {
flex-direction: column;
}
text-align: left;
input{
box-sizing: border-box;
width: 100%;
}
}
background-color: #575E75;
.col{
padding: 40px;
flex: 1;
}
}
#admin-message-list{
display: inline-block;
padding: 25px;
max-width: 1094px;
#admin-message-list-title{
text-align: left;
}
}
.admin-message{
text-align: left;
.admin-message-date{
color: #575E75;
font-size: 12px;
padding-bottom: 10px;
}
text-align: left;
border-radius: 8px;
padding: 16px;
background-color: #E5F0FF;
margin: 10px;
}
#force-account-rename-text{
h1, h3, p{
color: white;
}
}
.empty{
text-align: left;
.admin-message{
margin: 10px;
}
}
.banned-message-box{
margin: 20px;
text-align: left;
}
.join-flow-outer-content{
background-color: white;
border-radius: 16px;
color: #575e75;
max-width: 468px;
min-height: auto !important;
@media only screen and (max-width: 800px) {
margin: auto;
}
}
.banned-icon{
margin-right: 10px;
padding-top: 10px;
margin-bottom: -3px;
}
.modal-flush-bottom-button{
background-color: #855CD6;
}
.modal-flush-bottom-button:hover{
background-color: #855CD6;
}
.join-flow-outer-content{
border: solid 4px #818698;
border-radius: 21px;
}