Remove outdated gun actions
This commit is contained in:
parent
0681464817
commit
45eeb2d672
1 changed files with 1 additions and 751 deletions
|
|
@ -26,262 +26,10 @@ const LNDHealthMananger = require('../../../utils/lightningServices/errors')
|
||||||
const { enrollContentTokens, selfContentToken } = require('../../seed')
|
const { enrollContentTokens, selfContentToken } = require('../../seed')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('./SimpleGUN').GUNNode} GUNNode
|
|
||||||
* @typedef {import('./SimpleGUN').ISEA} ISEA
|
* @typedef {import('./SimpleGUN').ISEA} ISEA
|
||||||
* @typedef {import('./SimpleGUN').UserGUNNode} UserGUNNode
|
* @typedef {import('./SimpleGUN').UserGUNNode} UserGUNNode
|
||||||
* @typedef {import('shock-common').Schema.HandshakeRequest} HandshakeRequest
|
|
||||||
* @typedef {import('shock-common').Schema.StoredRequest} StoredReq
|
|
||||||
* @typedef {import('shock-common').Schema.Message} Message
|
|
||||||
* @typedef {import('shock-common').Schema.Outgoing} Outgoing
|
|
||||||
* @typedef {import('shock-common').Schema.PartialOutgoing} PartialOutgoing
|
|
||||||
* @typedef {import('shock-common').Schema.Order} Order
|
|
||||||
* @typedef {import('./SimpleGUN').Ack} Ack
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a an outgoing feed. The feed will have an initial special acceptance
|
|
||||||
* message. Returns a promise that resolves to the id of the newly-created
|
|
||||||
* outgoing feed.
|
|
||||||
*
|
|
||||||
* If an outgoing feed is already created for the recipient, then returns the id
|
|
||||||
* of that one.
|
|
||||||
* @param {string} withPublicKey Public key of the intended recipient of the
|
|
||||||
* outgoing feed that will be created.
|
|
||||||
* @throws {Error} If the outgoing feed cannot be created or if the initial
|
|
||||||
* message for it also cannot be created. These errors aren't coded as they are
|
|
||||||
* not meant to be caught outside of this module.
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
const __createOutgoingFeed = async (withPublicKey, user, SEA) => {
|
|
||||||
if (!user.is) {
|
|
||||||
throw new Error(ErrorCode.NOT_AUTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
const mySecret = require('../Mediator').getMySecret()
|
|
||||||
const encryptedForMeRecipientPub = await SEA.encrypt(withPublicKey, mySecret)
|
|
||||||
const ourSecret = await SEA.secret(
|
|
||||||
await Utils.pubToEpub(withPublicKey),
|
|
||||||
user._.sea
|
|
||||||
)
|
|
||||||
|
|
||||||
const maybeOutgoingID = await Utils.recipientToOutgoingID(withPublicKey)
|
|
||||||
|
|
||||||
let outgoingFeedID = ''
|
|
||||||
|
|
||||||
// if there was no stored outgoing, create an outgoing feed
|
|
||||||
if (typeof maybeOutgoingID !== 'string') {
|
|
||||||
/** @type {PartialOutgoing} */
|
|
||||||
const newPartialOutgoingFeed = {
|
|
||||||
with: encryptedForMeRecipientPub
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {string} */
|
|
||||||
const newOutgoingFeedID = await new Promise((res, rej) => {
|
|
||||||
const _outFeedNode = user
|
|
||||||
.get(Key.OUTGOINGS)
|
|
||||||
//@ts-ignore
|
|
||||||
.set(newPartialOutgoingFeed, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res(_outFeedNode._.get)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
if (typeof newOutgoingFeedID !== 'string') {
|
|
||||||
throw new TypeError('typeof newOutgoingFeedID !== "string"')
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Message} */
|
|
||||||
const initialMsg = {
|
|
||||||
body: await SEA.encrypt(Constants.Misc.INITIAL_MSG, ourSecret),
|
|
||||||
timestamp: Date.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.OUTGOINGS)
|
|
||||||
.get(newOutgoingFeedID)
|
|
||||||
.get(Key.MESSAGES)
|
|
||||||
//@ts-ignore
|
|
||||||
.set(initialMsg, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
const encryptedForMeNewOutgoingFeedID = await SEA.encrypt(
|
|
||||||
newOutgoingFeedID,
|
|
||||||
mySecret
|
|
||||||
)
|
|
||||||
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.RECIPIENT_TO_OUTGOING)
|
|
||||||
.get(withPublicKey)
|
|
||||||
.put(encryptedForMeNewOutgoingFeedID, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
outgoingFeedID = newOutgoingFeedID
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise decrypt stored outgoing
|
|
||||||
else {
|
|
||||||
outgoingFeedID = maybeOutgoingID
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof outgoingFeedID === 'undefined') {
|
|
||||||
throw new TypeError(
|
|
||||||
'__createOutgoingFeed() -> typeof outgoingFeedID === "undefined"'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof outgoingFeedID !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
'__createOutgoingFeed() -> expected outgoingFeedID to be an string'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outgoingFeedID.length === 0) {
|
|
||||||
throw new TypeError(
|
|
||||||
'__createOutgoingFeed() -> expected outgoingFeedID to be a populated string.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return outgoingFeedID
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a request's ID, that should be found on the user's current handshake
|
|
||||||
* node, accept the request by creating an outgoing feed intended for the
|
|
||||||
* requestor, then encrypting and putting the id of this newly created outgoing
|
|
||||||
* feed on the response prop of the request.
|
|
||||||
* @param {string} requestID The id for the request to accept.
|
|
||||||
* @param {GUNNode} gun
|
|
||||||
* @param {UserGUNNode} user Pass only for testing purposes.
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @param {typeof __createOutgoingFeed} outgoingFeedCreator Pass only
|
|
||||||
* for testing. purposes.
|
|
||||||
* @throws {Error} Throws if trying to accept an invalid request, or an error on
|
|
||||||
* gun's part.
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const acceptRequest = async (
|
|
||||||
requestID,
|
|
||||||
gun,
|
|
||||||
user,
|
|
||||||
SEA,
|
|
||||||
outgoingFeedCreator = __createOutgoingFeed
|
|
||||||
) => {
|
|
||||||
if (!user.is) {
|
|
||||||
throw new Error(ErrorCode.NOT_AUTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handshakeAddress = await Utils.tryAndWait(async (_, user) => {
|
|
||||||
const addr = await user.get(Key.CURRENT_HANDSHAKE_ADDRESS).then()
|
|
||||||
|
|
||||||
if (typeof addr !== 'string') {
|
|
||||||
throw new TypeError("typeof addr !== 'string'")
|
|
||||||
}
|
|
||||||
|
|
||||||
return addr
|
|
||||||
})
|
|
||||||
|
|
||||||
const {
|
|
||||||
response: encryptedForUsIncomingID,
|
|
||||||
from: senderPublicKey
|
|
||||||
} = await Utils.tryAndWait(async gun => {
|
|
||||||
const hr = await gun
|
|
||||||
.get(Key.HANDSHAKE_NODES)
|
|
||||||
.get(handshakeAddress)
|
|
||||||
.get(requestID)
|
|
||||||
.then()
|
|
||||||
|
|
||||||
if (!Schema.isHandshakeRequest(hr)) {
|
|
||||||
throw new Error(ErrorCode.TRIED_TO_ACCEPT_AN_INVALID_REQUEST)
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr
|
|
||||||
})
|
|
||||||
|
|
||||||
/** @type {string} */
|
|
||||||
const requestorEpub = await Utils.pubToEpub(senderPublicKey)
|
|
||||||
|
|
||||||
const ourSecret = await SEA.secret(requestorEpub, user._.sea)
|
|
||||||
if (typeof ourSecret !== 'string') {
|
|
||||||
throw new TypeError("typeof ourSecret !== 'string'")
|
|
||||||
}
|
|
||||||
|
|
||||||
const incomingID = await SEA.decrypt(encryptedForUsIncomingID, ourSecret)
|
|
||||||
if (typeof incomingID !== 'string') {
|
|
||||||
throw new TypeError("typeof incomingID !== 'string'")
|
|
||||||
}
|
|
||||||
|
|
||||||
const newlyCreatedOutgoingFeedID = await outgoingFeedCreator(
|
|
||||||
senderPublicKey,
|
|
||||||
user,
|
|
||||||
SEA
|
|
||||||
)
|
|
||||||
|
|
||||||
const mySecret = require('../Mediator').getMySecret()
|
|
||||||
const encryptedForMeIncomingID = await SEA.encrypt(incomingID, mySecret)
|
|
||||||
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_INCOMING)
|
|
||||||
.get(senderPublicKey)
|
|
||||||
.put(encryptedForMeIncomingID, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// NOTE: perform non-reversable actions before destructive actions
|
|
||||||
// In case any of the non-reversable actions reject.
|
|
||||||
// In this case, writing to the response is the non-revesarble op.
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const encryptedForUsOutgoingID = await SEA.encrypt(
|
|
||||||
newlyCreatedOutgoingFeedID,
|
|
||||||
ourSecret
|
|
||||||
)
|
|
||||||
//why await if you dont need the response?
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
gun
|
|
||||||
.get(Key.HANDSHAKE_NODES)
|
|
||||||
.get(handshakeAddress)
|
|
||||||
.get(requestID)
|
|
||||||
.put(
|
|
||||||
{
|
|
||||||
response: encryptedForUsOutgoingID
|
|
||||||
},
|
|
||||||
ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} pass
|
* @param {string} pass
|
||||||
|
|
@ -374,438 +122,6 @@ const generateHandshakeAddress = async () => {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} pub
|
|
||||||
* @throws {Error}
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const cleanup = async pub => {
|
|
||||||
const user = require('../Mediator').getUser()
|
|
||||||
|
|
||||||
const outGoingID = await Utils.recipientToOutgoingID(pub)
|
|
||||||
|
|
||||||
const promises = []
|
|
||||||
|
|
||||||
promises.push(
|
|
||||||
/** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_INCOMING)
|
|
||||||
.get(pub)
|
|
||||||
.put(null, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
|
|
||||||
promises.push(
|
|
||||||
/** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.RECIPIENT_TO_OUTGOING)
|
|
||||||
.get(pub)
|
|
||||||
.put(null, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
|
|
||||||
promises.push(
|
|
||||||
/** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_LAST_REQUEST_SENT)
|
|
||||||
.get(pub)
|
|
||||||
.put(null, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
|
|
||||||
if (outGoingID) {
|
|
||||||
promises.push(
|
|
||||||
/** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.OUTGOINGS)
|
|
||||||
.get(outGoingID)
|
|
||||||
.put(null, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(promises)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} recipientPublicKey
|
|
||||||
* @param {GUNNode} gun
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @throws {Error|TypeError}
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const sendHandshakeRequest = async (recipientPublicKey, gun, user, SEA) => {
|
|
||||||
if (!user.is) {
|
|
||||||
throw new Error(ErrorCode.NOT_AUTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
await cleanup(recipientPublicKey)
|
|
||||||
|
|
||||||
if (typeof recipientPublicKey !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
`recipientPublicKey is not string, got: ${typeof recipientPublicKey}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientPublicKey.length === 0) {
|
|
||||||
throw new TypeError('recipientPublicKey is an string of length 0')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientPublicKey === user.is.pub) {
|
|
||||||
throw new Error('Do not send a request to yourself')
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before recipientEpub')
|
|
||||||
|
|
||||||
/** @type {string} */
|
|
||||||
const recipientEpub = await Utils.pubToEpub(recipientPublicKey)
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before mySecret')
|
|
||||||
|
|
||||||
const mySecret = require('../Mediator').getMySecret()
|
|
||||||
logger.info('sendHR() -> before ourSecret')
|
|
||||||
const ourSecret = await SEA.secret(recipientEpub, user._.sea)
|
|
||||||
|
|
||||||
// check if successful handshake is present
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before alreadyHandshaked')
|
|
||||||
|
|
||||||
/** @type {boolean} */
|
|
||||||
const alreadyHandshaked = await Utils.successfulHandshakeAlreadyExists(
|
|
||||||
recipientPublicKey
|
|
||||||
)
|
|
||||||
|
|
||||||
if (alreadyHandshaked) {
|
|
||||||
throw new Error(ErrorCode.ALREADY_HANDSHAKED)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before maybeLastRequestIDSentToUser')
|
|
||||||
|
|
||||||
// check that we have already sent a request to this user, on his current
|
|
||||||
// handshake node
|
|
||||||
const maybeLastRequestIDSentToUser = await Utils.tryAndWait((_, user) =>
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_LAST_REQUEST_SENT)
|
|
||||||
.get(recipientPublicKey)
|
|
||||||
.then()
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before currentHandshakeAddress')
|
|
||||||
|
|
||||||
const currentHandshakeAddress = await Utils.tryAndWait(
|
|
||||||
gun =>
|
|
||||||
Common.Utils.makePromise(res => {
|
|
||||||
gun
|
|
||||||
.user(recipientPublicKey)
|
|
||||||
.get(Key.CURRENT_HANDSHAKE_ADDRESS)
|
|
||||||
.once(
|
|
||||||
data => {
|
|
||||||
res(data)
|
|
||||||
},
|
|
||||||
{ wait: 1000 }
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
data => typeof data !== 'string'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (typeof currentHandshakeAddress !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
'expected current handshake address found on recipients user node to be an string'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof maybeLastRequestIDSentToUser === 'string') {
|
|
||||||
if (maybeLastRequestIDSentToUser.length < 5) {
|
|
||||||
throw new TypeError(
|
|
||||||
'sendHandshakeRequest() -> maybeLastRequestIDSentToUser.length < 5'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastRequestIDSentToUser = maybeLastRequestIDSentToUser
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before alreadyContactedOnCurrHandshakeNode')
|
|
||||||
|
|
||||||
const hrInHandshakeNode = await Utils.tryAndWait(
|
|
||||||
gun =>
|
|
||||||
new Promise(res => {
|
|
||||||
gun
|
|
||||||
.get(Key.HANDSHAKE_NODES)
|
|
||||||
.get(currentHandshakeAddress)
|
|
||||||
.get(lastRequestIDSentToUser)
|
|
||||||
.once(data => {
|
|
||||||
res(data)
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
// force retry on undefined in case the undefined was a false negative
|
|
||||||
v => typeof v === 'undefined'
|
|
||||||
)
|
|
||||||
|
|
||||||
const alreadyContactedOnCurrHandshakeNode =
|
|
||||||
typeof hrInHandshakeNode !== 'undefined'
|
|
||||||
|
|
||||||
if (alreadyContactedOnCurrHandshakeNode) {
|
|
||||||
throw new Error(ErrorCode.ALREADY_REQUESTED_HANDSHAKE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before __createOutgoingFeed')
|
|
||||||
|
|
||||||
const outgoingFeedID = await __createOutgoingFeed(
|
|
||||||
recipientPublicKey,
|
|
||||||
user,
|
|
||||||
SEA
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before encryptedForUsOutgoingFeedID')
|
|
||||||
|
|
||||||
const encryptedForUsOutgoingFeedID = await SEA.encrypt(
|
|
||||||
outgoingFeedID,
|
|
||||||
ourSecret
|
|
||||||
)
|
|
||||||
|
|
||||||
const timestamp = Date.now()
|
|
||||||
|
|
||||||
/** @type {HandshakeRequest} */
|
|
||||||
const handshakeRequestData = {
|
|
||||||
from: user.is.pub,
|
|
||||||
response: encryptedForUsOutgoingFeedID,
|
|
||||||
timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
const encryptedForMeRecipientPublicKey = await SEA.encrypt(
|
|
||||||
recipientPublicKey,
|
|
||||||
mySecret
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info('sendHR() -> before newHandshakeRequestID')
|
|
||||||
/** @type {string} */
|
|
||||||
const newHandshakeRequestID = await new Promise((res, rej) => {
|
|
||||||
const hr = gun
|
|
||||||
.get(Key.HANDSHAKE_NODES)
|
|
||||||
.get(currentHandshakeAddress)
|
|
||||||
//@ts-ignore
|
|
||||||
.set(handshakeRequestData, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(`Error trying to create request: ${ack.err}`))
|
|
||||||
} else {
|
|
||||||
res(hr._.get)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_LAST_REQUEST_SENT)
|
|
||||||
.get(recipientPublicKey)
|
|
||||||
.put(newHandshakeRequestID, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
// This needs to come before the write to sent requests. Because that write
|
|
||||||
// triggers Jobs.onAcceptedRequests and it in turn reads from request-to-user
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {StoredReq}
|
|
||||||
*/
|
|
||||||
const storedReq = {
|
|
||||||
sentReqID: await SEA.encrypt(newHandshakeRequestID, mySecret),
|
|
||||||
recipientPub: encryptedForMeRecipientPublicKey,
|
|
||||||
handshakeAddress: await SEA.encrypt(currentHandshakeAddress, mySecret),
|
|
||||||
timestamp
|
|
||||||
}
|
|
||||||
//why await if you dont need the response?
|
|
||||||
await /** @type {Promise<void>} */ (new Promise((res, rej) => {
|
|
||||||
//@ts-ignore
|
|
||||||
user.get(Key.STORED_REQS).set(storedReq, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(
|
|
||||||
new Error(
|
|
||||||
`Error saving newly created request to sent requests: ${ack.err}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the message id.
|
|
||||||
* @param {string} recipientPublicKey
|
|
||||||
* @param {string} body
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @returns {Promise<import('shock-common').Schema.ChatMessage>} The message id.
|
|
||||||
*/
|
|
||||||
const sendMessageNew = async (recipientPublicKey, body, user, SEA) => {
|
|
||||||
if (!user.is) {
|
|
||||||
throw new Error(ErrorCode.NOT_AUTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof recipientPublicKey !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
`expected recipientPublicKey to be an string, but instead got: ${typeof recipientPublicKey}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientPublicKey.length === 0) {
|
|
||||||
throw new TypeError(
|
|
||||||
'expected recipientPublicKey to be an string of length greater than zero'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof body !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
`expected message to be an string, instead got: ${typeof body}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body.length === 0) {
|
|
||||||
throw new TypeError(
|
|
||||||
'expected message to be an string of length greater than zero'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const outgoingID = await Utils.recipientToOutgoingID(recipientPublicKey)
|
|
||||||
|
|
||||||
if (outgoingID === null) {
|
|
||||||
throw new Error(
|
|
||||||
`Could not fetch an outgoing id for user: ${recipientPublicKey}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const recipientEpub = await Utils.pubToEpub(recipientPublicKey)
|
|
||||||
const ourSecret = await SEA.secret(recipientEpub, user._.sea)
|
|
||||||
if (typeof ourSecret !== 'string') {
|
|
||||||
throw new TypeError("sendMessage() -> typeof ourSecret !== 'string'")
|
|
||||||
}
|
|
||||||
const encryptedBody = await SEA.encrypt(body, ourSecret)
|
|
||||||
|
|
||||||
const newMessage = {
|
|
||||||
body: encryptedBody,
|
|
||||||
timestamp: Date.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
const msgNode = user
|
|
||||||
.get(Key.OUTGOINGS)
|
|
||||||
.get(outgoingID)
|
|
||||||
.get(Key.MESSAGES)
|
|
||||||
.set(newMessage, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res({
|
|
||||||
body,
|
|
||||||
id: msgNode._.get,
|
|
||||||
outgoing: true,
|
|
||||||
timestamp: newMessage.timestamp
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the message id.
|
|
||||||
* @param {string} recipientPublicKey
|
|
||||||
* @param {string} body
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @returns {Promise<string>} The message id.
|
|
||||||
*/
|
|
||||||
const sendMessage = async (recipientPublicKey, body, user, SEA) =>
|
|
||||||
(await sendMessageNew(recipientPublicKey, body, user, SEA)).id
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} recipientPub
|
|
||||||
* @param {string} msgID
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const deleteMessage = async (recipientPub, msgID, user) => {
|
|
||||||
if (!user.is) {
|
|
||||||
throw new Error(ErrorCode.NOT_AUTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof recipientPub !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
`expected recipientPublicKey to be an string, but instead got: ${typeof recipientPub}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientPub.length === 0) {
|
|
||||||
throw new TypeError(
|
|
||||||
'expected recipientPublicKey to be an string of length greater than zero'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof msgID !== 'string') {
|
|
||||||
throw new TypeError(
|
|
||||||
`expected msgID to be an string, instead got: ${typeof msgID}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msgID.length === 0) {
|
|
||||||
throw new TypeError(
|
|
||||||
'expected msgID to be an string of length greater than zero'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const outgoingID = await Utils.recipientToOutgoingID(recipientPub)
|
|
||||||
|
|
||||||
if (outgoingID === null) {
|
|
||||||
throw new Error(`Could not fetch an outgoing id for user: ${recipientPub}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.OUTGOINGS)
|
|
||||||
.get(outgoingID)
|
|
||||||
.get(Key.MESSAGES)
|
|
||||||
.get(msgID)
|
|
||||||
.put(null, ack => {
|
|
||||||
if (ack.err && typeof ack.err !== 'number') {
|
|
||||||
rej(new Error(ack.err))
|
|
||||||
} else {
|
|
||||||
res()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string|null} avatar
|
* @param {string|null} avatar
|
||||||
* @param {UserGUNNode} user
|
* @param {UserGUNNode} user
|
||||||
|
|
@ -924,52 +240,6 @@ const setSeedServiceData = (encryptedSeedServiceData, user) =>
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} initialMsg
|
|
||||||
* @param {string} recipientPublicKey
|
|
||||||
* @param {GUNNode} gun
|
|
||||||
* @param {UserGUNNode} user
|
|
||||||
* @param {ISEA} SEA
|
|
||||||
* @throws {Error|TypeError}
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const sendHRWithInitialMsg = async (
|
|
||||||
initialMsg,
|
|
||||||
recipientPublicKey,
|
|
||||||
gun,
|
|
||||||
user,
|
|
||||||
SEA
|
|
||||||
) => {
|
|
||||||
/** @type {boolean} */
|
|
||||||
const alreadyHandshaked = await Utils.tryAndWait(
|
|
||||||
(_, user) =>
|
|
||||||
new Promise((res, rej) => {
|
|
||||||
user
|
|
||||||
.get(Key.USER_TO_INCOMING)
|
|
||||||
.get(recipientPublicKey)
|
|
||||||
.once(inc => {
|
|
||||||
if (typeof inc !== 'string') {
|
|
||||||
res(false)
|
|
||||||
} else if (inc.length === 0) {
|
|
||||||
rej(
|
|
||||||
new Error(
|
|
||||||
`sendHRWithInitialMsg()-> obtained encryptedIncomingId from user-to-incoming an string but of length 0`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
res(true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!alreadyHandshaked) {
|
|
||||||
await sendHandshakeRequest(recipientPublicKey, gun, user, SEA)
|
|
||||||
}
|
|
||||||
|
|
||||||
await sendMessage(recipientPublicKey, initialMsg, user, SEA)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} SpontPaymentOptions
|
* @typedef {object} SpontPaymentOptions
|
||||||
* @prop {Common.Schema.OrderTargetType} type
|
* @prop {Common.Schema.OrderTargetType} type
|
||||||
|
|
@ -1035,7 +305,7 @@ const sendSpontaneousPayment = async (
|
||||||
|
|
||||||
logger.info('sendPayment() -> will now create order:')
|
logger.info('sendPayment() -> will now create order:')
|
||||||
|
|
||||||
/** @type {Order} */
|
/** @type {import('shock-common').Schema.Order} */
|
||||||
const order = {
|
const order = {
|
||||||
amount: amount.toString(),
|
amount: amount.toString(),
|
||||||
from: getUser()._.sea.pub,
|
from: getUser()._.sea.pub,
|
||||||
|
|
@ -1395,18 +665,6 @@ const saveChannelsBackup = async (backups, user, SEA) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} pub
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
const disconnect = async pub => {
|
|
||||||
if (!(await Utils.successfulHandshakeAlreadyExists(pub))) {
|
|
||||||
throw new Error('No handshake exists for this pub')
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all([cleanup(pub), generateHandshakeAddress()])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
|
|
@ -1789,15 +1047,9 @@ const initWall = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
__createOutgoingFeed,
|
|
||||||
acceptRequest,
|
|
||||||
authenticate,
|
authenticate,
|
||||||
blacklist,
|
blacklist,
|
||||||
generateHandshakeAddress,
|
generateHandshakeAddress,
|
||||||
sendHandshakeRequest,
|
|
||||||
deleteMessage,
|
|
||||||
sendMessage,
|
|
||||||
sendHRWithInitialMsg,
|
|
||||||
setAvatar,
|
setAvatar,
|
||||||
setDisplayName,
|
setDisplayName,
|
||||||
sendPayment,
|
sendPayment,
|
||||||
|
|
@ -1805,14 +1057,12 @@ module.exports = {
|
||||||
setBio,
|
setBio,
|
||||||
saveSeedBackup,
|
saveSeedBackup,
|
||||||
saveChannelsBackup,
|
saveChannelsBackup,
|
||||||
disconnect,
|
|
||||||
setLastSeenApp,
|
setLastSeenApp,
|
||||||
createPost,
|
createPost,
|
||||||
deletePost,
|
deletePost,
|
||||||
follow,
|
follow,
|
||||||
unfollow,
|
unfollow,
|
||||||
initWall,
|
initWall,
|
||||||
sendMessageNew,
|
|
||||||
sendSpontaneousPayment,
|
sendSpontaneousPayment,
|
||||||
createPostNew,
|
createPostNew,
|
||||||
setDefaultSeedProvider,
|
setDefaultSeedProvider,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue