Merge pull request #7455 from tomlum/force-account-rename-design-test

Force Account Rename Design Check
This commit is contained in:
Tom Lum 2023-03-16 15:49:54 -04:00 committed by GitHub
commit 6bba4c2583
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 304 additions and 0 deletions

View file

@ -140,6 +140,7 @@ module.exports.selectToken = state => get(state, ['session', 'session', 'user',
module.exports.selectIsAdmin = state => get(state, ['session', 'session', 'permissions', 'admin'], false); module.exports.selectIsAdmin = state => get(state, ['session', 'session', 'permissions', 'admin'], false);
module.exports.selectIsSocial = state => get(state, ['session', 'session', 'permissions', 'social'], false); module.exports.selectIsSocial = state => get(state, ['session', 'session', 'permissions', 'social'], false);
module.exports.selectIsEducator = state => get(state, ['session', 'session', 'permissions', 'educator'], false); module.exports.selectIsEducator = state => get(state, ['session', 'session', 'permissions', 'educator'], false);
module.exports.selectBannedUser = state => get(state, ['session', 'session', 'user'], false);
module.exports.selectProjectCommentsGloballyEnabled = state => module.exports.selectProjectCommentsGloballyEnabled = state =>
get(state, ['session', 'session', 'flags', 'project_comments_enabled'], false); get(state, ['session', 'session', 'flags', 'project_comments_enabled'], false);
module.exports.selectStudioCommentsGloballyEnabled = state => module.exports.selectStudioCommentsGloballyEnabled = state =>

View file

@ -423,6 +423,13 @@
"view": "microbit/microbit", "view": "microbit/microbit",
"title": "micro:bit" "title": "micro:bit"
}, },
{
"name": "Account Blocked",
"pattern": "^/accounts/banned-response/?(\\?.*)?$",
"routeAlias": "/accounts/banned-response/?$",
"view": "banned-splash/banned-splash",
"title": "Account Blocked"
},
{ {
"name": "vernier", "name": "vernier",
"pattern": "^/vernier/?(\\?.*)?$", "pattern": "^/vernier/?(\\?.*)?$",

View file

@ -0,0 +1,193 @@
const injectIntl = require('react-intl').injectIntl;
const intlShape = require('react-intl').intlShape;
// const FormattedMessage = require('react-intl').FormattedMessage;
const React = require('react');
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 Page = require('../../components/page/www/page.jsx');
const render = require('../../lib/render.jsx');
require('../../components/extension-landing/extension-landing.scss');
require('./banned-splash.scss');
const validateUsernameConfirm = (username, usernameConfirm) => {
if (!usernameConfirm) {
// return 'Username is required';
} else if (username !== usernameConfirm) {
return "Usernames don't match";
}
};
const BannedSplash = ({hasSession, user, adminMessages, getAdminMessages, intl}) => {
React.useEffect(() => {
if (user && user.username && user.token){
getAdminMessages(user.username, user.token);
}
}, [user]);
if (hasSession && (!user || !user.banned)){
window.location = '/';
}
if (user && user.banned){
return (<div id="banned-splash">
<div id="force-account-rename">
<div id="force-account-rename-inner">
<div
id="force-account-rename-text"
className="col"
>
<h1>Account Blocked</h1>
<h3>To recover access to your account, change your username.</h3>
<p>Your scratch account <b>{user && user.username}</b> has been temporarily blocked because your usernamed appears to contain personal information.</p>
<p>This is a serious privacy issue. When you share information like this, it is visible to everyone on the internet, so please be careful what you share</p>
<p>When creating an username, please remember to avoid using last names, school names, or other private information in your username.</p>
</div>
<div className="col">
<Formik
initialValues={{
newUsername: '',
newUsernameConfirm: ''
}}
// validate={this.validateForm}
validateOnBlur={false}
validateOnChange={false}
// onSubmit={this.handleValidSubmit}
>
{props => {
const {
errors,
// handleSubmit,
// isSubmitting,
setFieldError,
setFieldTouched,
setFieldValue,
// touched,
validateField,
values
} = props;
return (
<JoinFlowStep
description={<span>Make sure the username you chose is aligned with <a href="/community_guidelines">Scratch's Community Guidelines</a></span>}
innerClassName="change-username-inner"
outerClassName="change-username-outer"
title={'Change your Username'}
// waiting={isSubmitting}
// onSubmit={handleSubmit}
nextButton={'Change'}
>
<div>
<FormikInput
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
// className={'join-flow-input'}
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={newUsername => validateUsername(newUsername)}
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);
}}
// onFocus={() => this.handleFocused('username')}
/* eslint-enable react/jsx-no-bind */
// onSetRef={this.handleSetUsernameRef}
/>
<FormikInput
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className={'join-flow-input'}
error={errors.newUsernameConfirm}
id="newUsernameConfirm"
name="newUsernameConfirm"
placeholder={'Type your new username again'}
spellCheck={false}
// toolTip={this.state.focused === 'username' && !touched.username &&
// this.props.intl.formatMessage({id: 'registration.usernameAdviceShort'})}
/* eslint-disable react/jsx-no-bind */
validate={newUsernameConfirm => validateUsernameConfirm(values.newUsername, newUsernameConfirm)}
validationClassName="validation-left validation-full-width-input"
onBlur={() => {
validateField('newUsernameConfirm');
}}
onChange={e => {
setFieldValue('newUsernameConfirm', e.target.value.substring(0, 30));
setFieldTouched('newUsernameConfirm');
setFieldError('newUsernameConfirm', null);
}}
/* eslint-enable react/jsx-no-bind */
// onSetRef={this.handleSetUsernameRef}
/>
</div>
</JoinFlowStep>);
}}
</Formik>
</div>
</div>
</div>
<div id="admin-message-list">
<div id="admin-message-list-title">
<b>Here are your past admin notifications</b>
</div>
{adminMessages.map(message => (
<div
className="admin-message"
key={message.id}
>
<div className="admin-message-date">
{new Date(message.datetime_created).toDateString()}
</div>
<div dangerouslySetInnerHTML={{__html: message.message}} />
</div>
))}
</div>
</div>
);
}
return <div />;
};
BannedSplash.propTypes = {
intl: intlShape.isRequired
};
// LET SESSION MAKE BANNED BE A STRING THAT SAYS THE KIND OF BANNED
// THIS IS AN API CHANGE ON THE SESSION
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,103 @@
@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%;
}
}
#banned-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: #4d97ff;
.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;
}
}