Skip to content
This repository was archived by the owner on Dec 14, 2023. It is now read-only.

Commit 28b0f70

Browse files
authored
Merge pull request #282 from CoderDojo/prevent-raspberry-pword
Handle login response: account linked to raspberry pi
2 parents b471d6a + c8ba1e6 commit 28b0f70

File tree

5 files changed

+65
-19
lines changed

5 files changed

+65
-19
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"ok":false,
3+
"why":"raspberry-linked"
4+
}

cypress/integration/authenticatiion/login_spec.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('Login Page', () => {
5959
cy.get(page.emailFormatError).should('be.visible');
6060
});
6161

62-
it('should show an error when the login fails (on mock server this is only when the incorrect email is provided)', () => {
62+
it('should show an error when the login fails (on mock server this is only when [email protected] email is provided)', () => {
6363
cy.server();
6464
cy.route('POST', '/api/2.0/users/login', 'fx:loginFail').as('loginFail');
6565
cy.get(page.loginFailed).should('not.be.visible');
@@ -71,6 +71,18 @@ describe('Login Page', () => {
7171
cy.get(page.loginFailed).should('be.visible');
7272
});
7373

74+
it('should show an raspberry linked error when login fails because linked (on mock server this is only when [email protected] email is provided)', () => {
75+
cy.server();
76+
cy.route('POST', '/api/2.0/users/login', 'fx:loginRaspberryFail').as('loginRaspberryFail');
77+
cy.get(page.loginFailed).should('not.be.visible');
78+
cy.get(page.email).click();
79+
cy.get(page.email).type('[email protected]');
80+
cy.get(page.password).type('rightpassword');
81+
cy.get(page.login).click();
82+
cy.wait('@loginRaspberryFail');
83+
cy.get(page.loginRaspberryFailed).should('be.visible');
84+
});
85+
7486
it('should show both requirement errors when a login is attempted if no email and no password is provided', () => {
7587
cy.get(page.emailFormatError).should('not.be.visible'); // TODO: Should be emailReqError?
7688
cy.get(page.passwordReqError).should('not.be.visible');

cypress/pages/login.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default {
1010
emailFormatError: '.cd-login__email-format-err',
1111
passwordReqError: '.cd-login__password-req-err',
1212
loginFailed: '.cd-login__login-failed',
13+
loginRaspberryFailed: '.cd-login__raspberry-linked',
1314
registerLink: '.cd-login__register a',
1415
forgotPasswordLink: '.cd-login__forgot-password a',
15-
};
16+
};

json-server/server.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ server.post('/api/2.0/users/login', (req, res) => {
160160
res.send();
161161
} else if (req.body.email === '[email protected]') {
162162
res.send({ ok: false, why: 'invalid-password' });
163+
} else if (req.body.email === '[email protected]') {
164+
res.send({ ok: false, why: 'raspberry-linked' });
163165
} else {
164166
res.send({ ok: false, why: 'user-not-found' });
165167
}

src/users/cd-login.vue

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,36 @@
1212
</div>
1313
<div class="row">
1414
<div class="cd-login__box">
15-
<form @submit.prevent="login">
16-
<div class="form-group">
17-
<label>{{ $t('Email') }}</label>
18-
<input class="form-control" data-vv-name="email" data-vv-validate-on="blur" type="email" v-model="email" v-validate="'required|email'" novalidate/>
19-
</div>
20-
<p class="cd-login__email-req-err text-danger" v-show="errors.has('email:required')">{{ $t('Email is required') }}</p>
21-
<p class="cd-login__email-format-err text-danger" v-show="errors.has('email:email')">{{ $t('Email should be in the format: [email protected]') }}</p>
22-
<div class="form-group">
23-
<label>Password</label>
24-
<input class="form-control" data-vv-name="password" data-vv-validate-on="blur" type="password" v-model="password" v-validate="'required'" />
25-
</div>
26-
<p class="cd-login__password-req-err text-danger" v-show="errors.has('password:required')">{{ $t('Password is required') }}</p>
27-
<input class="cd-login__button btn btn-primary" type="submit" value="Login" />
28-
</form>
29-
<p v-show="errors.has('loginFailed')" class="cd-login__login-failed text-danger">{{ $t('There was a problem logging in: {msg}', {msg: $t('Invalid email or password') }) }}</p>
30-
<p class="cd-login__forgot-password"><a href="/reset">{{ $t('Forgot password?') }}</a></p>
31-
<p class="cd-login__register">{{ $t("Don't have an account?") }} <a :href="registerUrl">{{ $t('Register here') }}</a></p>
15+
<span v-show="errors.first('loginFailed') !== 'raspberry-linked'">
16+
<form @submit.prevent="login">
17+
<div class="form-group">
18+
<label>{{ $t('Email') }}</label>
19+
<input class="form-control" data-vv-name="email" data-vv-validate-on="blur" type="email" v-model="email" v-validate="'required|email'" novalidate/>
20+
</div>
21+
<p class="cd-login__email-req-err text-danger" v-show="errors.has('email:required')">{{ $t('Email is required') }}</p>
22+
<p class="cd-login__email-format-err text-danger" v-show="errors.has('email:email')">{{ $t('Email should be in the format: [email protected]') }}</p>
23+
<div class="form-group">
24+
<label>Password</label>
25+
<input class="form-control" data-vv-name="password" data-vv-validate-on="blur" type="password" v-model="password" v-validate="'required'" />
26+
</div>
27+
<p class="cd-login__password-req-err text-danger" v-show="errors.has('password:required')">{{ $t('Password is required') }}</p>
28+
<input class="cd-login__button btn btn-primary" type="submit" value="Login" />
29+
</form>
30+
<p v-show="errors.has('loginFailed')" class="cd-login__login-failed text-danger">{{ $t('There was a problem logging in: {msg}', {msg: $t('Invalid email or password') }) }}</p>
31+
<p class="cd-login__forgot-password"><a href="/reset">{{ $t('Forgot password?') }}</a></p>
32+
<p class="cd-login__register">{{ $t("Don't have an account?") }} <a :href="registerUrl">{{ $t('Register here') }}</a></p>
33+
</span>
34+
<span v-show="errors.first('loginFailed') === 'raspberry-linked'" class="cd-login__raspberry-linked">
35+
<p>
36+
{{ $t('The account for email {msg} is linked to a My Raspberry Pi account.', { msg: email }) }}
37+
</p>
38+
<p>
39+
<a :href="`/rpi/login?user=${email}`">{{$t('Login through My Raspberry Pi.')}}</a>
40+
</p>
41+
<p>
42+
<a href='#' v-on:click.prevent="resetForm()" >{{$t('Use different Coder Dojo account.')}}</a>
43+
</p>
44+
</span>
3245
</div>
3346
</div>
3447
</div>
@@ -73,13 +86,23 @@
7386
async validateForm() {
7487
return this.$validator.validateAll();
7588
},
89+
resetForm() {
90+
this.email = '';
91+
this.password = '';
92+
if (this.errors && this.errors.clear) {
93+
this.errors.clear();
94+
}
95+
},
7696
redirectTo(url) {
7797
location.href = url;
7898
},
7999
async login() {
80100
const valid = await this.validateForm();
81101
if (valid) {
82102
const response = await UserService.login(this.email, this.password);
103+
if (this.errors && this.errors.clear) {
104+
this.errors.clear();
105+
}
83106
if (response.body.ok === false) {
84107
this.errors.add({
85108
field: 'loginFailed',
@@ -123,5 +146,9 @@
123146
.primary-button;
124147
margin-bottom: 48px;
125148
}
149+
150+
&__raspberry-linked {
151+
display: block;
152+
}
126153
}
127154
</style>

0 commit comments

Comments
 (0)