diff --git a/src/commands/createAppInvite.js b/src/commands/createAppInvite.js index 0767123..f4407bb 100644 --- a/src/commands/createAppInvite.js +++ b/src/commands/createAppInvite.js @@ -1,4 +1,8 @@ -const invitesService = require('../services/invitesService'); +const nostrService = require('../services/nostrService'); +const InvitesServiceProvider = require('../services/invitesService'); +const invitesService = new InvitesServiceProvider({ + nostrService, +}).provide(); module.exports = async function createAppInvite(inviterNpub) { const appInvite = await invitesService.createAppInvite(inviterNpub); diff --git a/src/services/index.js b/src/services/index.js index f4c61c3..efb197d 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -2,10 +2,14 @@ class ServicesProvider { constructor() {} provide() { - const invitesService = require('../services/invitesService'); const nostrService = require('../services/nostrService'); const loginService = require('../services/loginService'); + const InvitesServiceProvider = require('../services/invitesService'); + const invitesService = new InvitesServiceProvider({ + nostrService, + }).provide(); + const SessionServiceProvider = require('../services/sessionService'); const sessionService = new SessionServiceProvider({ invitesService, diff --git a/src/services/invitesService.js b/src/services/invitesService.js index 16d7805..75e96f1 100644 --- a/src/services/invitesService.js +++ b/src/services/invitesService.js @@ -4,117 +4,133 @@ const nostrService = require('./nostrService'); const models = require('../models'); const errors = require('../errors'); -async function appInviteExists(inviteUuid) { - const invite = await models.AppInviteCreated.findOne({ - where: { uuid: inviteUuid }, - }); - if (invite) { - return true; - } - return false; -} - -async function getAppInvite(inviteUuid) { - const invite = await models.AppInviteCreated.findOne({ - where: { uuid: inviteUuid }, - }); - return invite; -} - -async function isAppInviteSpent(appInviteUuid) { - const signUpChallengeCompleted = - await models.SignUpChallengeCompleted.findOne({ - where: { - app_invite_uuid: appInviteUuid, - }, - }); - - if (signUpChallengeCompleted) { - return true; - } - return false; -} - -async function createAppInvite(inviterPubKey) { - return await models.AppInviteCreated.create({ - uuid: uuid.v7(), - inviter_pub_key: inviterPubKey, - created_at: new Date().toISOString(), - }); -} - -async function createSignUpChallenge(appInviteUuid) { - if (!(await appInviteExists(appInviteUuid))) { - throw new errors.NotFoundError("Invite doesn't exist."); +class InvitesServiceProvider { + constructor({ nostrService }) { + this.nostrService = nostrService; } - if (await isAppInviteSpent(appInviteUuid)) { - throw new errors.AlreadyUsedError('Invite has already been used.'); - } - - const nostrChallenge = await nostrService.createNostrChallenge(); - - return await models.SignUpChallengeCreated.create({ - uuid: uuid.v7(), - nostr_challenge_uuid: nostrChallenge.uuid, - app_invite_uuid: appInviteUuid, - created_at: new Date().toISOString(), - }); -} - -async function verifySignUpChallenge(signedEvent) { - const challengeTag = signedEvent.tags.find((tag) => tag[0] === 'challenge'); - const challenge = challengeTag[1]; - - const nostrChallenge = await nostrService.getNostrChallenge(null, challenge); - - const signUpChallenge = await models.SignUpChallengeCreated.findOne({ - where: { - nostr_challenge_uuid: nostrChallenge.uuid, - }, - }); - - if (await nostrService.hasNostrChallengeBeenCompleted(challenge)) { - throw new errors.AlreadyUsedError('This challenge has already been used.'); - } - - const completedNostrChallenge = - await nostrService.verifyNostrChallenge(signedEvent); - - const completedSignUpChallenge = await models.SignUpChallengeCompleted.create( - { - uuid: uuid.v7(), - nostr_challenge_completed_uuid: completedNostrChallenge.uuid, - app_invite_uuid: signUpChallenge.app_invite_uuid, - public_key: completedNostrChallenge.public_key, - created_at: new Date().toISOString(), + provide() { + async function appInviteExists(inviteUuid) { + const invite = await models.AppInviteCreated.findOne({ + where: { uuid: inviteUuid }, + }); + if (invite) { + return true; + } + return false; } - ); - return completedSignUpChallenge; -} + async function getAppInvite(inviteUuid) { + const invite = await models.AppInviteCreated.findOne({ + where: { uuid: inviteUuid }, + }); + return invite; + } -async function isPublicKeySignedUp(publicKey) { - const signUpChallengeCompleted = - await models.SignUpChallengeCompleted.findOne({ - where: { - public_key: publicKey, - }, - }); + async function isAppInviteSpent(appInviteUuid) { + const signUpChallengeCompleted = + await models.SignUpChallengeCompleted.findOne({ + where: { + app_invite_uuid: appInviteUuid, + }, + }); - if (signUpChallengeCompleted) { - return true; + if (signUpChallengeCompleted) { + return true; + } + return false; + } + + async function createAppInvite(inviterPubKey) { + return await models.AppInviteCreated.create({ + uuid: uuid.v7(), + inviter_pub_key: inviterPubKey, + created_at: new Date().toISOString(), + }); + } + + async function createSignUpChallenge(appInviteUuid) { + if (!(await appInviteExists(appInviteUuid))) { + throw new errors.NotFoundError("Invite doesn't exist."); + } + + if (await isAppInviteSpent(appInviteUuid)) { + throw new errors.AlreadyUsedError('Invite has already been used.'); + } + + const nostrChallenge = await nostrService.createNostrChallenge(); + + return await models.SignUpChallengeCreated.create({ + uuid: uuid.v7(), + nostr_challenge_uuid: nostrChallenge.uuid, + app_invite_uuid: appInviteUuid, + created_at: new Date().toISOString(), + }); + } + + async function verifySignUpChallenge(signedEvent) { + const challengeTag = signedEvent.tags.find( + (tag) => tag[0] === 'challenge' + ); + const challenge = challengeTag[1]; + + const nostrChallenge = await nostrService.getNostrChallenge( + null, + challenge + ); + + const signUpChallenge = await models.SignUpChallengeCreated.findOne({ + where: { + nostr_challenge_uuid: nostrChallenge.uuid, + }, + }); + + if (await nostrService.hasNostrChallengeBeenCompleted(challenge)) { + throw new errors.AlreadyUsedError( + 'This challenge has already been used.' + ); + } + + const completedNostrChallenge = + await nostrService.verifyNostrChallenge(signedEvent); + + const completedSignUpChallenge = + await models.SignUpChallengeCompleted.create({ + uuid: uuid.v7(), + nostr_challenge_completed_uuid: completedNostrChallenge.uuid, + app_invite_uuid: signUpChallenge.app_invite_uuid, + public_key: completedNostrChallenge.public_key, + created_at: new Date().toISOString(), + }); + + return completedSignUpChallenge; + } + + async function isPublicKeySignedUp(publicKey) { + const signUpChallengeCompleted = + await models.SignUpChallengeCompleted.findOne({ + where: { + public_key: publicKey, + }, + }); + + if (signUpChallengeCompleted) { + return true; + } + + return false; + } + + return { + appInviteExists, + getAppInvite, + isAppInviteSpent, + createAppInvite, + createSignUpChallenge, + verifySignUpChallenge, + isPublicKeySignedUp, + }; } - - return false; } -module.exports = { - appInviteExists, - getAppInvite, - isAppInviteSpent, - createAppInvite, - createSignUpChallenge, - verifySignUpChallenge, - isPublicKeySignedUp, -}; +module.exports = InvitesServiceProvider;