Created
November 26, 2023 10:25
-
-
Save lucky-rydar/689fd08b511ee7f9bf6eddd222c02127 to your computer and use it in GitHub Desktop.
security lab 6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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