storing contact details works
This commit is contained in:
parent
00fc6bb258
commit
6b52d06b3e
10 changed files with 138 additions and 15 deletions
13
src/middlewares/attachPublicKeyMiddleware.js
Normal file
13
src/middlewares/attachPublicKeyMiddleware.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
const sessionService = require('../services/sessionService');
|
||||||
|
|
||||||
|
async function attachPublicKeyMiddleware(req, res, next) {
|
||||||
|
|
||||||
|
const publicKey = await sessionService.getPublicKeyRelatedToSession(
|
||||||
|
req.cookies.sessionUuid
|
||||||
|
)
|
||||||
|
req.cookies.publicKey = publicKey;
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = attachPublicKeyMiddleware;
|
||||||
13
src/middlewares/rejectIfNotAuthorizedMiddleware.js
Normal file
13
src/middlewares/rejectIfNotAuthorizedMiddleware.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
const sessionService = require('../services/sessionService');
|
||||||
|
|
||||||
|
async function rejectIfNotAuthorizedMiddleware(req, res, next) {
|
||||||
|
if (!(await sessionService.isSessionAuthorized(req.cookies.sessionUuid))) {
|
||||||
|
return res.status(403).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Your session is not authorized.'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = rejectIfNotAuthorizedMiddleware;
|
||||||
|
|
@ -13,25 +13,19 @@ async function createSessionMiddleware(req, res, next) {
|
||||||
|
|
||||||
const sessionUuid = req.cookies.sessionUuid;
|
const sessionUuid = req.cookies.sessionUuid;
|
||||||
|
|
||||||
console.log("Running cookie middleware")
|
|
||||||
|
|
||||||
if (!sessionUuid) {
|
if (!sessionUuid) {
|
||||||
console.log("Found no cookie")
|
|
||||||
const newSession = await setAndPersistNewSession(res);
|
const newSession = await setAndPersistNewSession(res);
|
||||||
req.cookies.sessionUuid = newSession.uuid;
|
req.cookies.sessionUuid = newSession.uuid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sessionUuid) {
|
if (sessionUuid) {
|
||||||
console.log(`Found a cookie ${sessionUuid}`)
|
|
||||||
if (!(await sessionService.isSessionValid(sessionUuid))) {
|
if (!(await sessionService.isSessionValid(sessionUuid))) {
|
||||||
console.log("But it's not valid")
|
|
||||||
const newSession = await setAndPersistNewSession(res);
|
const newSession = await setAndPersistNewSession(res);
|
||||||
req.cookies.sessionUuid = newSession.uuid;
|
req.cookies.sessionUuid = newSession.uuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Moving on...")
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
27
src/models/ContactDetailsSet.js
Normal file
27
src/models/ContactDetailsSet.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
const { DataTypes } = require('sequelize');
|
||||||
|
const sequelize = require('../database');
|
||||||
|
|
||||||
|
const ContactDetailsSet = sequelize.define('ContactDetailsSet', {
|
||||||
|
uuid: {
|
||||||
|
type: DataTypes.UUID,
|
||||||
|
allowNull: false,
|
||||||
|
unique: true,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
public_key: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
encrypted_contact_details: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
tableName: 'contact_details_set'
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = ContactDetailsSet;
|
||||||
|
|
@ -45,6 +45,12 @@ class ContactDetails {
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getEncryptedContactDetails() {
|
||||||
|
const jsonString = JSON.stringify(this.details);
|
||||||
|
const encryptedContactDetails = await window.nostr.nip04.encrypt(await window.nostr.getPublicKey(), jsonString);
|
||||||
|
return encryptedContactDetails;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let contactDetails;
|
let contactDetails;
|
||||||
|
|
@ -67,4 +73,21 @@ window.onload = () => {
|
||||||
input.value = '';
|
input.value = '';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('#submit-details-button')
|
||||||
|
.addEventListener(
|
||||||
|
'click',
|
||||||
|
async () => {
|
||||||
|
const encryptedContactDetails = await contactDetails.getEncryptedContactDetails();
|
||||||
|
await fetch('/api/set-contact-details',
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ encryptedContactDetails })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -3,12 +3,14 @@ const express = require('express');
|
||||||
const invitesService = require('../services/invitesService');
|
const invitesService = require('../services/invitesService');
|
||||||
const nostrService = require('../services/nostrService');
|
const nostrService = require('../services/nostrService');
|
||||||
const sessionService = require('../services/sessionService');
|
const sessionService = require('../services/sessionService');
|
||||||
|
const profileService = require('../services/profileService');
|
||||||
const errors = require('../errors');
|
const errors = require('../errors');
|
||||||
|
const attachPublicKeyMiddleware = require('../middlewares/attachPublicKeyMiddleware');
|
||||||
|
const rejectIfNotAuthorizedMiddleware = require('../middlewares/rejectIfNotAuthorizedMiddleware');
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.get('/signup/nostr-challenge', async (req, res) => {
|
router.get('/signup/nostr-challenge', async (req, res) => {
|
||||||
console.log("I'm heeeere")
|
|
||||||
const inviteUuid = req.cookies.inviteUuid;
|
const inviteUuid = req.cookies.inviteUuid;
|
||||||
|
|
||||||
let signUpChallenge;
|
let signUpChallenge;
|
||||||
|
|
@ -89,4 +91,30 @@ router.post("/signup/nostr-verify", async (req, res) => {
|
||||||
return res.status(200).json({ success: true });
|
return res.status(200).json({ success: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/set-contact-details",
|
||||||
|
rejectIfNotAuthorizedMiddleware,
|
||||||
|
attachPublicKeyMiddleware,
|
||||||
|
async (req, res) => {
|
||||||
|
const encryptedContactDetails = req.body.encryptedContactDetails;
|
||||||
|
const publicKey = req.cookies.publicKey;
|
||||||
|
|
||||||
|
if (!encryptedContactDetails) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Missing contact details.'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await profileService.setContactDetails(
|
||||||
|
publicKey,
|
||||||
|
encryptedContactDetails
|
||||||
|
)
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
message: 'Contact details set successfully.'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
||||||
|
|
@ -51,23 +51,19 @@ async function verifyNostrChallenge(signedEvent) {
|
||||||
const challengeTag = signedEvent.tags.find(tag => tag[0] === "challenge");
|
const challengeTag = signedEvent.tags.find(tag => tag[0] === "challenge");
|
||||||
const challenge = challengeTag[1];
|
const challenge = challengeTag[1];
|
||||||
|
|
||||||
console.log("Checking if fresh")
|
|
||||||
if (!(await isNostrChallengeFresh(challenge))) {
|
if (!(await isNostrChallengeFresh(challenge))) {
|
||||||
throw TimeoutError("Challenge expired, request new one.");
|
throw TimeoutError("Challenge expired, request new one.");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Checking if completed")
|
|
||||||
if (await hasNostrChallengeBeenCompleted(challenge)) {
|
if (await hasNostrChallengeBeenCompleted(challenge)) {
|
||||||
throw new errors.AlreadyUsedError("Challenge already used, request new one.");
|
throw new errors.AlreadyUsedError("Challenge already used, request new one.");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Checking if valid")
|
|
||||||
const isSignatureValid = verifyEvent(signedEvent);
|
const isSignatureValid = verifyEvent(signedEvent);
|
||||||
if (!isSignatureValid) {
|
if (!isSignatureValid) {
|
||||||
throw new errors.InvalidSignatureError("Signature is not valid.");
|
throw new errors.InvalidSignatureError("Signature is not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Persisting")
|
|
||||||
return await NostrChallengeCompleted.create({
|
return await NostrChallengeCompleted.create({
|
||||||
'uuid': uuid.v7(),
|
'uuid': uuid.v7(),
|
||||||
challenge: challenge,
|
challenge: challenge,
|
||||||
|
|
|
||||||
17
src/services/profileService.js
Normal file
17
src/services/profileService.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
const uuid = require('uuid');
|
||||||
|
const ContactDetailsSet = require('../models/ContactDetailsSet');
|
||||||
|
|
||||||
|
async function setContactDetails(publicKey, encryptedContactDetails) {
|
||||||
|
return ContactDetailsSet.create(
|
||||||
|
{
|
||||||
|
'uuid': uuid.v7(),
|
||||||
|
public_key: publicKey,
|
||||||
|
encrypted_contact_details: encryptedContactDetails,
|
||||||
|
created_at: new Date().toISOString()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setContactDetails
|
||||||
|
};
|
||||||
|
|
@ -4,7 +4,6 @@ const SessionCreated = require('../models/SessionCreated');
|
||||||
const SessionRelatedToPublickey = require('../models/SessionRelatedToPublickey');
|
const SessionRelatedToPublickey = require('../models/SessionRelatedToPublickey');
|
||||||
|
|
||||||
const invitesService = require('./invitesService');
|
const invitesService = require('./invitesService');
|
||||||
|
|
||||||
const constants = require('../constants');
|
const constants = require('../constants');
|
||||||
|
|
||||||
async function createSession(sessionUuid) {
|
async function createSession(sessionUuid) {
|
||||||
|
|
@ -71,9 +70,23 @@ async function isSessionAuthorized(sessionUuid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPublicKeyRelatedToSession(sessionUuid) {
|
||||||
|
const sessionRelatedToPublickey = await SessionRelatedToPublickey.findOne(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
session_uuid: sessionUuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return sessionRelatedToPublickey.public_key;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createSession,
|
createSession,
|
||||||
isSessionValid,
|
isSessionValid,
|
||||||
relateSessionToPublicKey,
|
relateSessionToPublicKey,
|
||||||
isSessionAuthorized
|
isSessionAuthorized,
|
||||||
|
getPublicKeyRelatedToSession
|
||||||
}
|
}
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
<hr>
|
<hr>
|
||||||
<form onsubmit="return false">
|
<form onsubmit="return false">
|
||||||
<label>Pseudónimo (Nym):<input type="text" name="nym" id="nym-input"></label>
|
<label>Pseudónimo (Nym):<input type="text" name="nym" id="nym-input"></label>
|
||||||
|
|
||||||
<button id="submit-details-button" type="submit">Crear tu perfil</button>
|
|
||||||
<div id="contacts">
|
<div id="contacts">
|
||||||
<p>Añade métodos de contacto para poder hablar con otros miembros.</p>
|
<p>Añade métodos de contacto para poder hablar con otros miembros.</p>
|
||||||
<div class="badges">
|
<div class="badges">
|
||||||
|
|
@ -48,6 +46,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button id="submit-details-button" type="submit">Crear tu perfil</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue