mirror of
https://github.com/PretendoNetwork/website.git
synced 2026-03-21 17:24:28 -05:00
Removed ph cookie, users now supply password for online files
This commit is contained in:
parent
ecb07e7b02
commit
12d0a9206e
|
|
@ -34,6 +34,5 @@
|
|||
"gmail": {
|
||||
"user": "email@gmail.com",
|
||||
"pass": "app-password"
|
||||
},
|
||||
"aes_key": "hex key here"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
body.modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Removing until it's done */
|
||||
.setting-card a.edit,
|
||||
.sign-in-history a {
|
||||
|
|
@ -249,6 +253,99 @@ fieldset {
|
|||
background: #a9375b;
|
||||
}
|
||||
|
||||
div.online-files-modal-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
|
||||
z-index: 10;
|
||||
}
|
||||
div.online-files-modal-wrapper.hidden {
|
||||
display: none;
|
||||
}
|
||||
div.online-files-modal {
|
||||
background: #393b5f;
|
||||
padding: 48px;
|
||||
border-radius: 8px;
|
||||
text-align: left;
|
||||
width: min(660px, 90%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.online-files-modal h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
p.online-files-modal-caption {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
p.online-files-modal-caption span {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.online-files-modal-button-wrapper {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.online-files-modal-button-wrapper button {
|
||||
margin-left: 12px;
|
||||
width: fit-content;
|
||||
}
|
||||
.online-files-modal-button-wrapper button.cancel {
|
||||
background: none;
|
||||
}
|
||||
.online-files-modal-button-wrapper button.confirm {
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
button {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
display: block;
|
||||
font-family: Poppins, Arial, Helvetica, sans-serif;
|
||||
font-size: 1rem;
|
||||
height: fit-content;
|
||||
|
||||
background: var(--btn);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
color: var(--text);
|
||||
width: 100%;
|
||||
|
||||
transition: filter 300ms;
|
||||
pointer-events: all;
|
||||
cursor: pointer;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
input {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
display: block;
|
||||
font-family: Poppins, Arial, Helvetica, sans-serif;
|
||||
font-size: 1rem;
|
||||
background-color: black; /*change me*/
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
color: var(--text);
|
||||
width: calc(100% - 24px);
|
||||
}
|
||||
|
||||
input:focus {
|
||||
background-color: #4b5595;
|
||||
outline: none;
|
||||
transition: 150ms;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,4 +19,44 @@ document.getElementById('remove-discord-connection')?.addEventListener('click',
|
|||
}
|
||||
})
|
||||
.catch(console.log);
|
||||
});
|
||||
|
||||
const onlineFilesModal = document.querySelector('.online-files-modal-wrapper');
|
||||
const onlineFilesModalButtonConfirm = document.getElementById('onlineFilesConfirmButton');
|
||||
const onlineFilesModalButtonClose = document.getElementById('onlineFilesCloseButton');
|
||||
const onlineFilesModalPasswordInput = document.getElementById('password');
|
||||
|
||||
document.getElementById('download-cemu-files')?.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
|
||||
onlineFilesModal.classList.remove('hidden');
|
||||
});
|
||||
|
||||
onlineFilesModalButtonConfirm?.addEventListener('click', () => {
|
||||
fetch('/account/online-files', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
password: onlineFilesModalPasswordInput.value
|
||||
})
|
||||
})
|
||||
.then(response => response.blob())
|
||||
.then()
|
||||
.then(blob => URL.createObjectURL(blob))
|
||||
.then(blobUrl => {
|
||||
const a = document.createElement('a');
|
||||
a.href = blobUrl;
|
||||
a.setAttribute('download', 'Cemu Pretendo Online Files.zip');
|
||||
a.click();
|
||||
|
||||
onlineFilesModal.classList.add('hidden');
|
||||
})
|
||||
.catch(console.log);
|
||||
});
|
||||
|
||||
onlineFilesModalButtonClose?.addEventListener('click', () => {
|
||||
onlineFilesModal.classList.add('hidden');
|
||||
});
|
||||
|
|
@ -3,7 +3,7 @@ const database = require('../database');
|
|||
|
||||
async function pnidMiddleware(request, response, next) {
|
||||
// Verify the user is logged in
|
||||
if (!request.cookies.access_token || !request.cookies.refresh_token || !request.cookies.ph) {
|
||||
if (!request.cookies.access_token || !request.cookies.refresh_token) {
|
||||
return response.redirect(`/account/login?redirect=${request.originalUrl}`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ const logger = require('../logger');
|
|||
const config = require('../../config.json');
|
||||
|
||||
const { Router } = express;
|
||||
const aesKey = Buffer.from(config.aes_key, 'hex');
|
||||
|
||||
const stripe = new Stripe(config.stripe.secret_key);
|
||||
const router = new Router();
|
||||
|
|
@ -48,7 +47,7 @@ router.get('/', pnidMiddleware, async (request, response) => {
|
|||
renderData.tierLevel = pnid.get('connections.stripe.tier_level');
|
||||
renderData.account = account;
|
||||
renderData.isTester = account.access_level > 0;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
// Check if a Discord account is linked to the PNID
|
||||
if (account.connections.discord.id && account.connections.discord.id.trim() !== '') {
|
||||
|
|
@ -67,7 +66,7 @@ router.get('/', pnidMiddleware, async (request, response) => {
|
|||
renderData.discordAuthURL = discordAuthURL;
|
||||
}
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
response.render('account/account', renderData);
|
||||
});
|
||||
|
|
@ -86,18 +85,6 @@ router.post('/login', async (request, response) => {
|
|||
response.cookie('access_token', tokens.access_token, { domain: '.pretendo.network' });
|
||||
response.cookie('token_type', tokens.token_type, { domain: '.pretendo.network' });
|
||||
|
||||
const account = await util.getUserAccountData(request, response);
|
||||
|
||||
const hashedPassword = util.nintendoPasswordHash(password, account.pid);
|
||||
const hashedPasswordBuffer = Buffer.from(hashedPassword, 'hex');
|
||||
|
||||
const cipher = crypto.createCipheriv('aes-256-cbc', aesKey, Buffer.alloc(16));
|
||||
|
||||
let encryptedBody = cipher.update(hashedPasswordBuffer);
|
||||
encryptedBody = Buffer.concat([encryptedBody, cipher.final()]);
|
||||
|
||||
response.cookie('ph', encryptedBody.toString('hex'), { domain: '.pretendo.network' });
|
||||
|
||||
response.redirect(request.redirect || '/account');
|
||||
|
||||
} catch (error) {
|
||||
|
|
@ -157,7 +144,6 @@ router.get('/logout', async(_request, response) => {
|
|||
response.clearCookie('refresh_token', { domain: '.pretendo.network' });
|
||||
response.clearCookie('access_token', { domain: '.pretendo.network' });
|
||||
response.clearCookie('token_type', { domain: '.pretendo.network' });
|
||||
response.clearCookie('ph', { domain: '.pretendo.network' });
|
||||
|
||||
response.redirect('/');
|
||||
});
|
||||
|
|
@ -190,13 +176,11 @@ router.get('/connect/discord', pnidMiddleware, async (request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
router.get('/online-files', pnidMiddleware, async (request, response) => {
|
||||
router.post('/online-files', pnidMiddleware, async (request, response) => {
|
||||
const { account } = request;
|
||||
const { password } = request.body;
|
||||
|
||||
const decipher = crypto.createDecipheriv('aes-256-cbc', aesKey, Buffer.alloc(16));
|
||||
|
||||
let decryptedPasswordHash = decipher.update(Buffer.from(request.cookies.ph, 'hex'));
|
||||
decryptedPasswordHash = Buffer.concat([decryptedPasswordHash, decipher.final()]);
|
||||
const hashedPassword = util.nintendoPasswordHash(password, account.pid);
|
||||
|
||||
const miiNameBuffer = Buffer.alloc(0x16);
|
||||
const miiName = Buffer.from(account.mii.name, 'utf16le').swap16();
|
||||
|
|
@ -218,7 +202,7 @@ router.get('/online-files', pnidMiddleware, async (request, response) => {
|
|||
accountDat += 'SimpleAddressId=0\n';
|
||||
accountDat += `PrincipalId=${account.pid.toString(16)}\n`;
|
||||
accountDat += 'IsPasswordCacheEnabled=1\n';
|
||||
accountDat += `AccountPasswordCache=${decryptedPasswordHash.toString('hex')}`;
|
||||
accountDat += `AccountPasswordCache=${hashedPassword}`;
|
||||
|
||||
const onlineFiles = new AdmZip();
|
||||
|
||||
|
|
@ -227,7 +211,7 @@ router.get('/online-files', pnidMiddleware, async (request, response) => {
|
|||
onlineFiles.addFile('seeprom.bin', Buffer.alloc(0x200)); // nulled SEEPROM
|
||||
|
||||
response.status(200);
|
||||
response.set('Content-Disposition', 'attachment; filename="Online Files.zip');
|
||||
response.set('Content-Disposition', 'attachment; filename="Cemu Pretendo Online Files.zip');
|
||||
response.set('Content-Type', 'application/zip');
|
||||
|
||||
response.end(onlineFiles.toBuffer());
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ router.get('/', async (request, response) => {
|
|||
|
||||
const renderData = {};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ router.get('/', async (request, response) => {
|
|||
postList
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
@ -74,7 +74,7 @@ router.get('/:slug', async (request, response, next) => {
|
|||
postList,
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ router.get('/search', async (request, response) => {
|
|||
currentPage: request.params.slug
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
@ -30,7 +30,7 @@ router.get('/:slug', async (request, response, next) => {
|
|||
currentPage: request.params.slug
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ router.get('/', async (request, response) => {
|
|||
boards
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const router = new Router();
|
|||
router.get('/', async (request, response) => {
|
||||
const renderData = {};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ router.get('/', async (request, response) => {
|
|||
boards
|
||||
};
|
||||
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token && request.cookies.ph;
|
||||
renderData.isLoggedIn = request.cookies.access_token && request.cookies.refresh_token;
|
||||
|
||||
if (renderData.isLoggedIn) {
|
||||
const account = await util.getAccount(request, response);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ const stripe = new Stripe(config.stripe.secret_key);
|
|||
|
||||
logger.info('Setting up Middleware');
|
||||
app.use(morgan('dev'));
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
app.use(cookieParser());
|
||||
app.use(expressLocale({
|
||||
'priority': ['cookie', 'accept-language', 'map', 'default'],
|
||||
|
|
|
|||
|
|
@ -172,4 +172,16 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="online-files-modal-wrapper hidden">
|
||||
<div class="online-files-modal">
|
||||
<h1 class="title dot">Password</h1>
|
||||
<p class="online-files-modal-caption">Enter your PNID password to download Cemu files</p>
|
||||
<input name="password" id="password" type="password" required>
|
||||
<div class="online-files-modal-button-wrapper">
|
||||
<button class="cancel" id="onlineFilesCloseButton">Cancel</button>
|
||||
<button class="confirm" id="onlineFilesConfirmButton">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/account.js"></script>
|
||||
Loading…
Reference in New Issue
Block a user