@@ -1,9 +1,9 @@ | |||
# Eindwerk Projectopvolging & Facturatie | |||
## Team | |||
- Abraham | |||
- Abraham ? | |||
- Simon | |||
- Mus | |||
- Mus ? | |||
## Needed Pages | |||
- Homepage |
@@ -72,12 +72,67 @@ class UserController | |||
if ($delete->execute()) { | |||
$response->getBody()->write(json_encode($data)); | |||
return $response | |||
->withHeader('Content-Type', 'application/json'); | |||
->withHeader('Content-Type', 'application/json'); | |||
} | |||
} | |||
return $response->withStatus(401); | |||
} | |||
public function resetPass(Request $request, Response $response): Response | |||
{ | |||
$token = $request->getParsedBody()['token']; | |||
if (!$token) return $response->withStatus(401); | |||
$parsedBody = $request->getParsedBody(); | |||
$db = $this->container->get('db'); | |||
$query = $db->prepare(' | |||
UPDATE user | |||
SET password = :pass | |||
WHERE token = :token | |||
'); | |||
$query->bindValue(':token', $token); | |||
$query->bindValue(':pass', $parsedBody['password']); | |||
if ($query->execute()) { | |||
$response->getBody()->write('success'); | |||
} else { | |||
$response->getBody()->write($db->lastErrorMsg()); | |||
return $response->withStatus(403); | |||
} | |||
return $response; | |||
} | |||
public function resetPassMail(Request $request, Response $response): Response | |||
{ | |||
$parsedBody = $request->getParsedBody(); | |||
$db = $this->container->get('db'); | |||
$token = ''; | |||
$query = $db->prepare(' | |||
SELECT token | |||
FROM user | |||
WHERE email = :email | |||
'); | |||
// TODO put constraints on username | |||
$query->bindValue(':email', $_POST['email']); | |||
$result = $query->execute(); | |||
if ($query->execute()) { | |||
$response->getBody()->write(strval($db->lastInsertRowID())); | |||
while ($row = $result->fetchArray()) { | |||
$token = $row['token']; | |||
} | |||
$mail = $this->container->get('mail'); | |||
$mail->passwordReset($_POST['email'], $token); | |||
} else { | |||
$response->getBody()->write($db->lastErrorMsg()); | |||
return $response->withStatus(403); | |||
} | |||
return $response; | |||
} | |||
function login(Request $request, Response $response, array $args) | |||
{ | |||
$input = json_decode(file_get_contents('php://input'), true); |
@@ -66,7 +66,7 @@ class MailerService | |||
} | |||
} | |||
public function passwordReset(string $email, string $name, string $token) | |||
public function passwordReset(string $email) | |||
{ | |||
$mail = new PHPMailer(); | |||
@@ -84,11 +84,11 @@ class MailerService | |||
$mail->setFrom('gamer.iradotadez@gmail.com'); | |||
$url = explode(',', $_ENV['FRONTEND_URL'] ?: 'http://localhost:3000')[0]; | |||
$body = '<a href="' . $url . '/reset?token=' . $token . '">Click here to reset your password</a>'; | |||
$body = '<a href="' . $url . '/reset?email=' . $email . '">Click here to reset your password</a>'; | |||
$mail->addAddress($email); | |||
$textBody = 'Validate your email address: ' . $url . '/validate?token=' . $token; | |||
$textBody = 'Validate your email address: ' . $url . '/reset?token=' . $email; | |||
try { | |||
$mail->msgHTML($body); |
@@ -56,6 +56,12 @@ $app->group('/api', function (RouteCollectorProxy $group) { | |||
$group->post('/create', UserController::class . ':create'); | |||
$group->options('/create', PreflightAction::class); | |||
$group->post('/resetPass', UserController::class . ':resetPass'); | |||
$group->options('/resetPass', PreflightAction::class); | |||
$group->post('/resetPassMail', UserController::class . ':resetPassMail'); | |||
$group->options('/resetPassMail', PreflightAction::class); | |||
$group->post('/validate', UserController::class . ':validateToken') | |||
->add(JsonBodyParserMiddleware::class); | |||
$group->options('/validate', PreflightAction::class); | |||
@@ -133,7 +139,6 @@ $app->group('/api', function (RouteCollectorProxy $group) { | |||
$group->get('/getInvoices', InvoiceController::class . ':getAllInvoices'); | |||
$group->post('/updateInvoice', InvoiceController::class . ':updateInvoice'); | |||
})->add(AuthMiddleware::class); | |||
// Add Routing Middleware |
@@ -0,0 +1,129 @@ | |||
<template> | |||
<div> | |||
<div class="loginpage"> | |||
<div class="login"> | |||
<div class="login-form"> | |||
<h1>Forgot your password?</h1> | |||
<p class="login-desc"> | |||
Enter your email and we will send you an email <br />to reset your | |||
password! | |||
</p> | |||
<div class="logreg-button"> | |||
<nuxt-link to="/register">register</nuxt-link> | |||
</div> | |||
<div class="logreg-button"> | |||
<nuxt-link to="/login" class="active">login</nuxt-link> | |||
</div> | |||
<div> | |||
<FormulateForm @submit="sendResetMail($event)"> | |||
<FormulateInput | |||
type="text" | |||
name="Email" | |||
v-model="setEmail.email" | |||
label="Email" | |||
placeholder="Email" | |||
validation="required" | |||
/> | |||
<FormulateInput type="submit" label="RESET" /> | |||
</FormulateForm> | |||
</div> | |||
<nuxt-link v-if="validated" to="/login">Proceed to login</nuxt-link> | |||
</div> | |||
</div> | |||
<div class="right"> | |||
<h1 class="logo-txt">NAME</h1> | |||
<img src="~/assets/bg1.png" /> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
auth: false, | |||
data() { | |||
return { | |||
validated: false, | |||
token: this.$route.query.token, | |||
setEmail: { email: '' }, | |||
}; | |||
}, | |||
mounted() { | |||
// const token = this.$route.query.token; | |||
// if (token) { | |||
// this.$refs.validate.textContent = 'Validating email ...'; | |||
// this.$axios | |||
// .post('/validate', { token }) | |||
// .then((response) => { | |||
// this.$refs.validate.textContent = | |||
// 'Congratulations ’' + | |||
// response.data.name + | |||
// '’, your email is now validated!'; | |||
// this.validated = true; | |||
// }) | |||
// .catch((error) => { | |||
// console.error(error); | |||
// this.$refs.validate.textContent = 'Sorry, that is not a valid token.'; | |||
// }); | |||
// } | |||
}, | |||
methods: { | |||
sendResetMail(data) { | |||
console.log(this.setEmail.email); | |||
const taskData = new URLSearchParams(); | |||
taskData.append('email', this.setEmail.email); | |||
taskData.append('token', this.token); | |||
this.$axios | |||
.post('/resetPassMail', taskData) | |||
.then(() => {}) | |||
.catch((error) => { | |||
console.error(error); | |||
alert(error.message); | |||
}); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.loginpage { | |||
display: flex; | |||
height: 100vh; | |||
overflow: hidden; | |||
} | |||
.login { | |||
background-color: $white; | |||
width: 40%; | |||
} | |||
.right { | |||
background-color: $blue; | |||
width: 60%; | |||
} | |||
.login-form { | |||
margin-left: 20%; | |||
margin-top: 25%; | |||
font-family: 'Roboto', sans-serif; | |||
} | |||
img { | |||
margin-top: 200px; | |||
margin-left: 12%; | |||
max-width: 1400px; | |||
max-height: 1000px; | |||
display: block; | |||
} | |||
.logo-txt { | |||
color: white; | |||
float: right; | |||
font-family: 'Roboto', sans-serif; | |||
margin-right: 3%; | |||
} | |||
</style> |
@@ -42,7 +42,7 @@ | |||
</FormulateForm> | |||
<button class="logreg-button"> | |||
<nuxt-link to="/password-reset">Forgot password?</nuxt-link> | |||
<nuxt-link to="/forgot">Forgot password?</nuxt-link> | |||
</button> | |||
</div> | |||
</div> | |||
@@ -60,8 +60,8 @@ | |||
export default { | |||
components: {}, | |||
methods: { | |||
login(formData) { | |||
this.$auth | |||
async login(formData) { | |||
await this.$auth | |||
.loginWith('local', { data: formData }) | |||
.then(() => { | |||
this.$auth.setUser(formData.username); |
@@ -0,0 +1,90 @@ | |||
<template> | |||
<div> | |||
<div class="loginpage"> | |||
<div class="login"> | |||
<div class="login-form"> | |||
<h1>Welcome to WorkSpace</h1> | |||
<p ref="validate"> | |||
Thank you for registering, check your email to activate your | |||
account. | |||
</p> | |||
<nuxt-link v-if="validated" to="/login">Proceed to login</nuxt-link> | |||
</div> | |||
</div> | |||
<div class="right"> | |||
<h1 class="logo-txt">NAME</h1> | |||
<img src="~/assets/bg1.png" /> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
auth: false, | |||
data() { | |||
return { | |||
validated: false, | |||
}; | |||
}, | |||
mounted() { | |||
const token = this.$route.query.token; | |||
if (token) { | |||
this.$refs.validate.textContent = 'Validating email ...'; | |||
this.$axios | |||
.post('/validate', { token }) | |||
.then((response) => { | |||
this.$refs.validate.textContent = | |||
'Congratulations ’' + | |||
response.data.name + | |||
'’, your email is now validated!'; | |||
this.validated = true; | |||
}) | |||
.catch((error) => { | |||
console.error(error); | |||
this.$refs.validate.textContent = 'Sorry, that is not a valid token.'; | |||
}); | |||
} | |||
}, | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.loginpage { | |||
display: flex; | |||
height: 100vh; | |||
overflow: hidden; | |||
} | |||
.login { | |||
background-color: $white; | |||
width: 40%; | |||
} | |||
.right { | |||
background-color: $blue; | |||
width: 60%; | |||
} | |||
.login-form { | |||
margin-left: 20%; | |||
margin-top: 25%; | |||
font-family: 'Roboto', sans-serif; | |||
} | |||
img { | |||
margin-top: 200px; | |||
margin-left: 12%; | |||
max-width: 1400px; | |||
max-height: 1000px; | |||
display: block; | |||
} | |||
.logo-txt { | |||
color: white; | |||
float: right; | |||
font-family: 'Roboto', sans-serif; | |||
margin-right: 3%; | |||
} | |||
</style> |