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')
|
||||
|
||||
/**
|
||||
* @typedef {import('./SimpleGUN').GUNNode} GUNNode
|
||||
* @typedef {import('./SimpleGUN').ISEA} ISEA
|
||||
* @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} 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 {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
|
||||
* @prop {Common.Schema.OrderTargetType} type
|
||||
|
|
@ -1035,7 +305,7 @@ const sendSpontaneousPayment = async (
|
|||
|
||||
logger.info('sendPayment() -> will now create order:')
|
||||
|
||||
/** @type {Order} */
|
||||
/** @type {import('shock-common').Schema.Order} */
|
||||
const order = {
|
||||
amount: amount.toString(),
|
||||
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>}
|
||||
*/
|
||||
|
|
@ -1789,15 +1047,9 @@ const initWall = async () => {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
__createOutgoingFeed,
|
||||
acceptRequest,
|
||||
authenticate,
|
||||
blacklist,
|
||||
generateHandshakeAddress,
|
||||
sendHandshakeRequest,
|
||||
deleteMessage,
|
||||
sendMessage,
|
||||
sendHRWithInitialMsg,
|
||||
setAvatar,
|
||||
setDisplayName,
|
||||
sendPayment,
|
||||
|
|
@ -1805,14 +1057,12 @@ module.exports = {
|
|||
setBio,
|
||||
saveSeedBackup,
|
||||
saveChannelsBackup,
|
||||
disconnect,
|
||||
setLastSeenApp,
|
||||
createPost,
|
||||
deletePost,
|
||||
follow,
|
||||
unfollow,
|
||||
initWall,
|
||||
sendMessageNew,
|
||||
sendSpontaneousPayment,
|
||||
createPostNew,
|
||||
setDefaultSeedProvider,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue