Skip to content

Instantly share code, notes, and snippets.

@lucky-rydar
Created November 26, 2023 10:25
Show Gist options
  • Save lucky-rydar/689fd08b511ee7f9bf6eddd222c02127 to your computer and use it in GitHub Desktop.
Save lucky-rydar/689fd08b511ee7f9bf6eddd222c02127 to your computer and use it in GitHub Desktop.
security lab 6
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign In</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
window.onload = handleLoginResponse;
function handleLoginResponse() {
var token = JSON.parse(`<%- JSON.stringify(token) %>`);
sessionStorage.setItem('token', JSON.stringify(token));
window.location.href = '/';
}
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign In</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="main-container">
<div class="header-container">
<p class="header-text">Sign In</p>
<a href="/api/logout" class="header-link">Log out</a>
</div>
<div class="user-container">
<p class="user-text"></p>
</div>
<div class="login-form-container form-container">
<form class="login-form" action="/api/login" method="post">
<input type="text" name="username" placeholder="Username" class="login-input login-username">
<input type="password" name="password" placeholder="Password" class="login-input login-password">
<input type="submit" value="Sign In" class="login-submit">
</form>
</div>
<div class="error-container">
<p class="error-text"></p>
</div>
<div class="register-redirect">
<p>Don't have an account? <a href="/register" class="register-redirect-link">Register</a></p>
</div>
<div class="sso-redirect">
<p>LogIn with SSO <a href="/sso-login" class="sso-redirect-link">LogIn</a></p>
</div>
</div>
</body>
<script>
function handleLoginResponse() {
axios.get('/', {
headers: {
Authorization: token
}
})
.then((res) => {
const userText = document.querySelector('.user-text');
const loginForm = document.querySelector('.login-form-container');
const logoutLink = document.querySelector('.header-link');
console.log(res.data.username);
userText.innerHTML = `Welcome, you are loged in`;
loginForm.style.display = 'none';
logoutLink.style.opacity = '1';
document.querySelector('.header-text').style.opacity = '0';
document.querySelector('.register-redirect').style.opacity = '0';
document.querySelector('.sso-redirect').style.opacity = '0';
})
}
const token = sessionStorage.getItem('token');
const username = sessionStorage.getItem('username');
console.log(token);
if (token) {
handleLoginResponse();
}
const loginForm = document.querySelector('.login-form');
const loginUsername = document.querySelector('.login-username');
const loginPassword = document.querySelector('.login-password');
loginForm.addEventListener('submit', (e) => {
e.preventDefault();
const username = loginUsername.value;
const password = loginPassword.value;
console.log('login form submitted in html');
console.log(username, password);
axios.post('/api/login', {
username,
password
})
.then((res) => {
sessionStorage.setItem('token', JSON.stringify(res.data.token));
sessionStorage.setItem('username', JSON.stringify(res.data.username));
location.reload();
})
.catch((err) => {
console.log(err);
const errorText = document.querySelector('.error-text');
errorText.innerHTML = err.response.data;
})
});
const logoutLink = document.querySelector('.header-link');
logoutLink.addEventListener('click', (e) => {
e.preventDefault();
sessionStorage.removeItem('token');
location.reload();
})
</script>
<style>
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
display: grid;
justify-items: center;
align-items: center;
background-color: #3a3a3a;
}
.header-link {
opacity: 0;
}
.main-container {
width: 50%;
height: 70%;
display: grid;
justify-items: center;
align-items: center;
background-color: white;
border-radius: 7px;
box-shadow: 0px 0px 5px 2px black;
}
.error-container {
width: 100%;
height: 100%;
display: grid;
justify-items: center;
align-items: center;
}
.error-text {
width: 23%;
text-align: center;
margin: 0;
padding: 5px;
font-size: 12px;
font-weight: bold;
color: #8a0000;
border: 1px solid #8a0000;
background-color: #e58f8f;
opacity: 0;
}
.form-container {
align-self: flex-start;
display: grid;
justify-items: center;
align-items: center;
}
.login-form{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.login-input::placeholder {
color: #3a3a3a;
}
.login-input {
border: none;
border-bottom: 1px solid #3a3a3a;
margin-bottom: 10px;
border-radius: 3px;
outline: none;
padding: 10px 0px 5px 5px;
}
.login-submit {
width: 100%;
padding: 7px;
border: none;
border-radius: 5px;
color: white;
font-weight: bold;
background-color: #3a3a3a;
cursor: pointer;
outline: none;
}
</style>
</html>
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const { render } = require('ejs');
require('dotenv').config();
const app = express();
app.use(bodyParser.json());
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
let token = req.get('Authorization');
if (token) {
let parsed = JSON.parse(token);
const expires_date = new Date(parsed.expires_at);
const current_date = new Date();
console.log("Token expires at: " + expires_date);
console.log("Current date: " + current_date);
expires_date.setMinutes(expires_date.getMinutes() - 20);
if (expires_date < current_date) {
console.log("Token expired");
const refreshTokenRequest = {
url: `https://${process.env.DOMAIN}/oauth/token`,
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded',
Authorization: `Bearer ${process.env.ACCESS_TOKEN}`
},
form: {
grant_type: 'refresh_token',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
audience: process.env.AUDIENCE,
refresh_token: process.env.USER_REFRESH_TOKEN,
}
};
request(refreshTokenRequest, (error, response, body) => {
if (error) {
console.log(error);
return;
}
const data = JSON.parse(body);
process.env.USER_ACCESS_TOKEN = data.access_token;
const currentTime = new Date();
let expiresAt = new Date();
expiresAt.setSeconds(currentTime.getSeconds() + data.expires_in);
token = JSON.stringify({
token: data.access_token,
username: parsed.username,
expires_at: expiresAt
});
});
}
req.token = token;
}
next();
});
app.get('/callback', (req, res) => {
console.log("received callback request")
console.log(req.query);
const code = req.query.code;
const getTokenRequest = {
url: `https://${process.env.DOMAIN}/oauth/token`,
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
form: {
grant_type: 'authorization_code',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
code: code,
redirect_uri: 'http://localhost:3000/callback',
scope: 'openid+email'
}
};
request(getTokenRequest, (error, response, body) => {
if(error) {
console.log(error);
return res.status(500).json({ error: error });
}
const data = JSON.parse(body);
process.env.USER_ACCESS_TOKEN = data.access_token;
process.env.USER_REFRESH_TOKEN = data.refresh_token;
const currentTime = new Date();
let expiresAt = new Date();
expiresAt.setSeconds(currentTime.getSeconds() + data.expires_in);
console.log("Data: " + data);
console.log("Data at: " + data.access_token);
res.render('home', {
token: {
token: data.access_token,
expires_at: expiresAt
}
});
});
});
app.get('/sso-login', (req, res) => {
const redirect_uri = 'http://localhost:3000/callback';
res.redirect(`https://${process.env.DOMAIN}/authorize?response_type=code&client_id=${process.env.CLIENT_ID}&redirect_uri=${redirect_uri}&response_mode=query`);
});
app.post('/api/login', (req, res) => {
const { username, password } = req.body;
console.log("received login request")
console.log(username, password);
const getUserTokenRequest = {
url: `https://${process.env.DOMAIN}/oauth/token`,
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
form: {
grant_type: 'http://auth0.com/oauth/grant-type/password-realm',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
username: username,
password: password,
audience: process.env.AUDIENCE,
scope: 'offline_access',
realm: 'Username-Password-Authentication'
}
};
request(getUserTokenRequest, (error, response, body) => {
if (error) {
console.log(error);
return res.status(500).json({ error: error });
}
if(response.statusCode === 200) {
const data = JSON.parse(body);
process.env.USER_ACCESS_TOKEN = data.access_token;
process.env.USER_REFRESH_TOKEN = data.refresh_token;;
const currentTime = new Date();
let expiresAt = new Date();
expiresAt.setSeconds(currentTime.getSeconds() + data.expires_in);
console.log("Data: " + data.access_token);
res.status(200).json({
token: {
token: data.access_token,
expires_at: expiresAt
},
username: username,
});
}
else {
return res.status(response.statusCode).json(JSON.parse(body));
}
});
});
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
}
);
app.get('/api/logout', (req, res) => {
process.env.USER_ACCESS_TOKEN = null;
process.env.USER_REFRESH_TOKEN = null;
res.redirect('/');
} );
app.get('/register', (req, res) => {
res.sendFile(__dirname + '/register.html');
} );
app.post('/api/register', (req, res) => {
console.log("received register request")
console.log(req.body);
const createUserRequest = {
url: `https://${process.env.DOMAIN}/api/v2/users`,
method: 'POST',
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${process.env.ACCESS_TOKEN}`
},
form: {
email: req.body.email,
given_name: req.body.given_name,
family_name: req.body.family_name,
name: req.body.name,
nickname: req.body.nickname,
password: req.body.password,
connection: 'Username-Password-Authentication'
}
};
request(createUserRequest, (error, response, body) => {
if (error){
console.log(error);
return res.status(500).json({ error: error });
}
else {
console.log(response);
return res.status(response.statusCode).json(JSON.parse(body));
}
});
});
app.listen(3000, () => {
console.log('Webhook server is listening, port 3000');
const getTokenRequest = {
url: `https://${process.env.DOMAIN}/oauth/token`,
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
form: {
grant_type: 'client_credentials',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
audience: process.env.AUDIENCE,
}
};
request(getTokenRequest, (error, response, body) => {
if (error) {
console.log(error);
console.log(error)
return;
}
const data = JSON.parse(body);
process.env.ACCESS_TOKEN = data.access_token;
console.log(response.statusCode);
console.log(response.statusMessage)
// console.log(body);
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="main-container">
<div class="header-container">
<p class="header-text">Register</p>
</div>
<div class="register-form-container form-container">
<form class="register-form" action="/api/register" method="post">
<input type="text" name="email" placeholder="Email" class="register-input register-email">
<input type="text" name="givenName" placeholder="Given Name" class="register-input register-given-name">
<input type="text" name="familyName" placeholder="Family Name" class="register-input register-family-name">
<input type="text" name="name" placeholder="Username" class="register-input register-username">
<input type="text" name="nickname" placeholder="Nickname" class="register-input register-nickname">
<input type="password" name="password" placeholder="Password" class="register-input register-password">
<input type="submit" value="Register" class="register-submit">
</form>
</div>
<div class="error-container">
<p class="error-text"></p>
</div>
</div>
</body>
<script>
const token = sessionStorage.getItem('token');
if (token) {
window.location.href = '/';
}
const registerForm = document.querySelector('.register-form');
const errorText = document.querySelector('.error-text');
registerForm.addEventListener('submit', (e) => {
e.preventDefault();
const email = document.querySelector('.register-email').value;
const givenName = document.querySelector('.register-given-name').value;
const familyName = document.querySelector('.register-family-name').value;
const username = document.querySelector('.register-username').value;
const nickname = document.querySelector('.register-nickname').value;
const password = document.querySelector('.register-password').value;
axios.post('/api/register', {
email,
givenName,
familyName,
username,
nickname,
password
})
.then((res) => {
console.log(res.data);
// sessionStorage.setItem('token', res.data.token);
// sessionStorage.setItem('username', res.data.username);
window.location.href = '/';
})
.catch((err) => {
console.log(err.response.data);
errorText.innerHTML = err.response.data;
})
})
</script>
<style>
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
display: grid;
justify-items: center;
align-items: center;
background-color: #3a3a3a;
}
.header-link {
opacity: 0;
}
.main-container {
width: 50%;
height: 70%;
display: grid;
justify-items: center;
align-items: center;
background-color: white;
border-radius: 7px;
box-shadow: 0px 0px 5px 2px black;
}
.error-container {
width: 100%;
height: 100%;
display: grid;
justify-items: center;
align-items: center;
}
.error-text {
width: 23%;
text-align: center;
margin: 0;
padding: 5px;
font-size: 12px;
font-weight: bold;
color: #8a0000;
border: 1px solid #8a0000;
background-color: #e58f8f;
opacity: 0;
}
.form-container {
align-self: flex-start;
display: grid;
justify-items: center;
align-items: center;
}
.register-form{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.register-form::placeholder {
color: #3a3a3a;
}
.register-input {
border: none;
border-bottom: 1px solid #3a3a3a;
margin-bottom: 10px;
border-radius: 3px;
outline: none;
padding: 10px 0px 5px 5px;
}
.register-submit {
width: 100%;
padding: 7px;
border: none;
border-radius: 5px;
color: white;
font-weight: bold;
background-color: #3a3a3a;
cursor: pointer;
outline: none;
}
</style>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment