stuff really
This commit is contained in:
parent
8131de0c96
commit
545c54bf81
5 changed files with 130 additions and 76 deletions
|
|
@ -1,7 +1,14 @@
|
||||||
const DEFAULT_SESSION_DURATION_SECONDS = 60 * 60 * 24 * 30;
|
const DEFAULT_SESSION_DURATION_SECONDS = 60 * 60 * 24 * 30;
|
||||||
const DEFAULT_NOSTR_CHALLENGE_DURATION_SECONDS = 60 * 60 * 24 * 30;
|
const DEFAULT_NOSTR_CHALLENGE_DURATION_SECONDS = 60 * 60 * 24 * 30;
|
||||||
|
const DEFAULT_REDIRECT_DELAY = 3 * 1000; // 3seconds times milliseconds;
|
||||||
|
|
||||||
|
const API_PATHS = {
|
||||||
|
createProfile: '/createProfile',
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
DEFAULT_SESSION_DURATION_SECONDS,
|
DEFAULT_SESSION_DURATION_SECONDS,
|
||||||
DEFAULT_NOSTR_CHALLENGE_DURATION_SECONDS,
|
DEFAULT_NOSTR_CHALLENGE_DURATION_SECONDS,
|
||||||
|
API_PATHS,
|
||||||
|
DEFAULT_REDIRECT_DELAY,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
0
src/front/components/NostrSignUpButton.js
Normal file
0
src/front/components/NostrSignUpButton.js
Normal file
|
|
@ -1,6 +1,63 @@
|
||||||
const checkNostrExtension = require('../utils/checkNostrExtension');
|
const checkNostrExtension = require('../utils/checkNostrExtension');
|
||||||
|
const signupService = require('../services/signupService');
|
||||||
|
const constants = require('../../constants');
|
||||||
|
|
||||||
|
class NostrSignupButton {
|
||||||
|
constructor({ parentElement, id, onClickCallback }) {
|
||||||
|
this.element = null;
|
||||||
|
this.parentElement = parentElement;
|
||||||
|
this.id = id;
|
||||||
|
this.onClickCallback = onClickCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const thisButton = document.createElement('button');
|
||||||
|
thisButton.id = this.id;
|
||||||
|
thisButton.type = 'submit';
|
||||||
|
thisButton.className = 'button-large button-nostr';
|
||||||
|
|
||||||
|
const figure = document.createElement('figure');
|
||||||
|
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = '/img/white_ostrich.svg';
|
||||||
|
img.style.width = '40%';
|
||||||
|
img.style.margin = '-5% -5%';
|
||||||
|
|
||||||
|
figure.appendChild(img);
|
||||||
|
|
||||||
|
const paragraph = document.createElement('p');
|
||||||
|
paragraph.textContent = 'Alta con Nostr';
|
||||||
|
|
||||||
|
thisButton.appendChild(figure);
|
||||||
|
thisButton.appendChild(paragraph);
|
||||||
|
|
||||||
|
thisButton.addEventListener('click', () => {
|
||||||
|
this.onClickCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.element = thisButton;
|
||||||
|
this.parentElement.appendChild(this.element);
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
this.element.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nostrSignupArea = document.getElementById('nostr-signup-area');
|
||||||
|
const noExtensionNudges = document.getElementById('no-extension-nudges');
|
||||||
|
const signUpSuccessNotification = document.getElementById('sign-up-success');
|
||||||
|
|
||||||
const invitesFunction = () => {
|
const invitesFunction = () => {
|
||||||
|
const signupButton = new NostrSignupButton({
|
||||||
|
parentElement: nostrSignupArea,
|
||||||
|
id: 'nostr-signup-button',
|
||||||
|
onClickCallback: () => {
|
||||||
|
acceptInvite();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
signupButton.render();
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
checkNostrExtension(
|
checkNostrExtension(
|
||||||
window,
|
window,
|
||||||
|
|
@ -9,81 +66,27 @@ const invitesFunction = () => {
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
console.log('Nostr extension not present');
|
console.log('Nostr extension not present');
|
||||||
document.querySelector('#nostr-signup-button').disabled = true;
|
signupButton.disable();
|
||||||
document.querySelector('#no-extension-nudges').style.display = 'block';
|
noExtensionNudges.style.display = 'block';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const signUpConfirmation = document.querySelector('#sign-up-success');
|
|
||||||
|
|
||||||
function showConfirmationAndRedirect() {
|
function showConfirmationAndRedirect() {
|
||||||
signUpConfirmation.classList.add('revealed');
|
signUpSuccessNotification.classList.add('revealed');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/createProfile';
|
window.location.href = constants.API_PATHS.createProfile;
|
||||||
}, 5000);
|
}, constants.DEFAULT_REDIRECT_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function acceptInvite() {
|
async function acceptInvite() {
|
||||||
let challengeResponse;
|
const verifyResponse =
|
||||||
try {
|
await signupService.requestAndRespondSignUpChallenge();
|
||||||
challengeResponse = await fetch('/api/signup/nostr-challenge', {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`Something went wrong: ${error}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { challenge } = await challengeResponse.json();
|
|
||||||
|
|
||||||
let pubkey;
|
|
||||||
try {
|
|
||||||
pubkey = await window.nostr.getPublicKey();
|
|
||||||
} catch (error) {
|
|
||||||
document.querySelector('#rejected-nostr-nudges').style.display = 'block';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const event = {
|
|
||||||
kind: 22242,
|
|
||||||
created_at: Math.floor(Date.now() / 1000),
|
|
||||||
tags: [['challenge', challenge]],
|
|
||||||
content: 'Sign this challenge to authenticate',
|
|
||||||
pubkey: pubkey,
|
|
||||||
};
|
|
||||||
|
|
||||||
let signedEvent;
|
|
||||||
try {
|
|
||||||
signedEvent = await window.nostr.signEvent(event);
|
|
||||||
} catch (error) {
|
|
||||||
document.querySelector('#rejected-nostr-nudges').style.display = 'block';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let verifyResponse;
|
|
||||||
try {
|
|
||||||
verifyResponse = await fetch('/api/signup/nostr-verify', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(signedEvent),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`Something went wrong: ${error}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verifyResponse.ok) {
|
if (verifyResponse.ok) {
|
||||||
showConfirmationAndRedirect();
|
showConfirmationAndRedirect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const signUpButton = document.getElementById('nostr-signup-button');
|
|
||||||
signUpButton.addEventListener('click', () => {
|
|
||||||
acceptInvite();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
invitesFunction();
|
invitesFunction();
|
||||||
|
|
|
||||||
57
src/front/services/signupService.js
Normal file
57
src/front/services/signupService.js
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
const requestAndRespondSignUpChallenge = async () => {
|
||||||
|
let challengeResponse;
|
||||||
|
try {
|
||||||
|
challengeResponse = await fetch('/api/signup/nostr-challenge', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Something went wrong: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { challenge } = await challengeResponse.json();
|
||||||
|
|
||||||
|
let pubkey;
|
||||||
|
try {
|
||||||
|
pubkey = await window.nostr.getPublicKey();
|
||||||
|
} catch (error) {
|
||||||
|
document.querySelector('#rejected-nostr-nudges').style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const event = {
|
||||||
|
kind: 22242,
|
||||||
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
|
tags: [['challenge', challenge]],
|
||||||
|
content: 'Sign this challenge to authenticate',
|
||||||
|
pubkey: pubkey,
|
||||||
|
};
|
||||||
|
|
||||||
|
let signedEvent;
|
||||||
|
try {
|
||||||
|
signedEvent = await window.nostr.signEvent(event);
|
||||||
|
} catch (error) {
|
||||||
|
document.querySelector('#rejected-nostr-nudges').style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let verifyResponse;
|
||||||
|
try {
|
||||||
|
verifyResponse = await fetch('/api/signup/nostr-verify', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(signedEvent),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Something went wrong: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifyResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
requestAndRespondSignUpChallenge,
|
||||||
|
};
|
||||||
|
|
@ -21,21 +21,8 @@
|
||||||
/>
|
/>
|
||||||
</figure>
|
</figure>
|
||||||
<p>Usa tu extensión de Nostr para darte de alta:</p>
|
<p>Usa tu extensión de Nostr para darte de alta:</p>
|
||||||
<div>
|
<div id="nostr-signup-area">
|
||||||
<button
|
|
||||||
id="nostr-signup-button"
|
|
||||||
type="submit"
|
|
||||||
class="button-large button-nostr"
|
|
||||||
>
|
|
||||||
<figure>
|
|
||||||
<img
|
|
||||||
src="/img/white_ostrich.svg"
|
|
||||||
width="40%"
|
|
||||||
margin="-5% -5%"
|
|
||||||
/>
|
|
||||||
</figure>
|
|
||||||
<p>Alta con Nostr</p>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="rejected-nostr-nudges"
|
id="rejected-nostr-nudges"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue