Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: remove "already part of project" invite response #481

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion proto/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ message InviteResponse {
enum Decision {
REJECT = 0;
ACCEPT = 1;
ALREADY = 2;
}
bytes projectKey = 1;
Decision decision = 2;
Expand Down
1 change: 0 additions & 1 deletion src/generated/rpc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export interface InviteResponse {
export declare const InviteResponse_Decision: {
readonly REJECT: "REJECT";
readonly ACCEPT: "ACCEPT";
readonly ALREADY: "ALREADY";
readonly UNRECOGNIZED: "UNRECOGNIZED";
};
export type InviteResponse_Decision = typeof InviteResponse_Decision[keyof typeof InviteResponse_Decision];
Expand Down
12 changes: 1 addition & 11 deletions src/generated/rpc.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
/* eslint-disable */
import _m0 from "protobufjs/minimal.js";
import { EncryptionKeys } from "./keys.js";
export var InviteResponse_Decision = {
REJECT: "REJECT",
ACCEPT: "ACCEPT",
ALREADY: "ALREADY",
UNRECOGNIZED: "UNRECOGNIZED",
};
export var InviteResponse_Decision = { REJECT: "REJECT", ACCEPT: "ACCEPT", UNRECOGNIZED: "UNRECOGNIZED" };
export function inviteResponse_DecisionFromJSON(object) {
switch (object) {
case 0:
Expand All @@ -15,9 +10,6 @@ export function inviteResponse_DecisionFromJSON(object) {
case 1:
case "ACCEPT":
return InviteResponse_Decision.ACCEPT;
case 2:
case "ALREADY":
return InviteResponse_Decision.ALREADY;
case -1:
case "UNRECOGNIZED":
default:
Expand All @@ -30,8 +22,6 @@ export function inviteResponse_DecisionToNumber(object) {
return 0;
case InviteResponse_Decision.ACCEPT:
return 1;
case InviteResponse_Decision.ALREADY:
return 2;
case InviteResponse_Decision.UNRECOGNIZED:
default:
return -1;
Expand Down
12 changes: 1 addition & 11 deletions src/generated/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ export interface InviteResponse {
decision: InviteResponse_Decision;
}

export const InviteResponse_Decision = {
REJECT: "REJECT",
ACCEPT: "ACCEPT",
ALREADY: "ALREADY",
UNRECOGNIZED: "UNRECOGNIZED",
} as const;
export const InviteResponse_Decision = { REJECT: "REJECT", ACCEPT: "ACCEPT", UNRECOGNIZED: "UNRECOGNIZED" } as const;

export type InviteResponse_Decision = typeof InviteResponse_Decision[keyof typeof InviteResponse_Decision];

Expand All @@ -38,9 +33,6 @@ export function inviteResponse_DecisionFromJSON(object: any): InviteResponse_Dec
case 1:
case "ACCEPT":
return InviteResponse_Decision.ACCEPT;
case 2:
case "ALREADY":
return InviteResponse_Decision.ALREADY;
case -1:
case "UNRECOGNIZED":
default:
Expand All @@ -54,8 +46,6 @@ export function inviteResponse_DecisionToNumber(object: InviteResponse_Decision)
return 0;
case InviteResponse_Decision.ACCEPT:
return 1;
case InviteResponse_Decision.ALREADY:
return 2;
case InviteResponse_Decision.UNRECOGNIZED:
default:
return -1;
Expand Down
26 changes: 4 additions & 22 deletions src/invite-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class InviteApi extends TypedEmitter {
const isAlreadyMember = await this.#isMember(projectId)

if (isAlreadyMember) {
this.#sendAlreadyResponse({ peerId, projectId })
this.#sendRejectResponse({ peerId, projectId })
return
}

Expand Down Expand Up @@ -112,7 +112,7 @@ export class InviteApi extends TypedEmitter {

if (isAlreadyMember) {
for (const peerId of peersToRespondTo) {
await this.#sendAlreadyResponse({ peerId, projectId })
await this.#sendRejectResponse({ peerId, projectId })
}
return
}
Expand Down Expand Up @@ -145,10 +145,10 @@ export class InviteApi extends TypedEmitter {
throw new Error('Failed to join project')
}

// Respond to the remaining peers with ALREADY
// Reject the remaining peers
for (const peerId of peersToRespondTo) {
if (peerId === pendingInvite.fromPeerId) continue
this.#sendAlreadyResponse({ peerId, projectId })
this.#sendRejectResponse({ peerId, projectId })
}
}

Expand Down Expand Up @@ -182,24 +182,6 @@ export class InviteApi extends TypedEmitter {
})
}

/**
* Will not throw, will silently fail if the response fails to send.
*
* @param {{ peerId: string, projectId: string }} opts
*/
async #sendAlreadyResponse({ peerId, projectId }) {
const projectKey = Buffer.from(projectId, 'hex')
try {
await this.rpc.inviteResponse(peerId, {
projectKey,
decision: InviteResponse_Decision.ALREADY,
})
} catch (e) {
// Ignore errors trying to send an already response because the invitor
// will consider the invite failed anyway
}
}

/**
* Will not throw, will silently fail if the response fails to send.
*
Expand Down
4 changes: 2 additions & 2 deletions src/local-peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export class LocalPeers extends TypedEmitter {

/**
* Invite a peer to a project. Resolves with the response from the invitee:
* one of "ACCEPT", "REJECT", or "ALREADY" (already on project)
* "ACCEPT" or "REJECT"
*
* @param {string} peerId
* @param {object} options
Expand Down Expand Up @@ -309,7 +309,7 @@ export class LocalPeers extends TypedEmitter {
* @param {string} peerId id of the peer you want to respond to (publicKey of peer as hex string)
* @param {object} options
* @param {InviteResponse['projectKey']} options.projectKey project key of the invite you are responding to
* @param {InviteResponse['decision']} options.decision response to invite, one of "ACCEPT", "REJECT", or "ALREADY" (already on project)
* @param {InviteResponse['decision']} options.decision response to invite, either "ACCEPT" or "REJECT"
*/
async inviteResponse(peerId, options) {
await this.#waitForPendingConnections()
Expand Down
59 changes: 7 additions & 52 deletions tests/invite-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ test('Receiving invite for project that peer already belongs to', async (t) => {

t.is(
response,
LocalPeers.InviteResponse.ALREADY,
'invited peer automatically responds with "ALREADY"'
LocalPeers.InviteResponse.REJECT,
'invited peer automatically responds with "REJECT"'
)
})

Expand Down Expand Up @@ -242,8 +242,8 @@ test('Receiving invite for project that peer already belongs to', async (t) => {

t.is(
response,
LocalPeers.InviteResponse.ALREADY,
'invited peer automatically responds with "ALREADY"'
LocalPeers.InviteResponse.REJECT,
'invited peer automatically responds with "REJECT"'
)
})

Expand Down Expand Up @@ -292,7 +292,7 @@ test('Receiving invite for project that peer already belongs to', async (t) => {

const response2 = await r1.invite(peers[0].deviceId, invite)

t.is(response2, LocalPeers.InviteResponse.ALREADY)
t.is(response2, LocalPeers.InviteResponse.REJECT)
})

let inviteReceivedEventCount = 0
Expand Down Expand Up @@ -407,51 +407,6 @@ test('invitor disconnecting results in invite reject response not throwing', asy
const disconnect = replicate(r1, r2)
})

test('invitor disconnecting results in invite already response not throwing', async (t) => {
t.plan(3)

const { rpc: r1, projectKey, encryptionKeys } = setup()

const r2 = new LocalPeers()

let isMember = false

const inviteApi = new InviteApi({
rpc: r2,
queries: {
isMember: async () => {
return isMember
},
addProject: async () => {},
},
})

r1.on('peers', async (peers) => {
if (peers.length !== 1 || peers[0].status === 'disconnected') return

await t.exception(() => {
const invite = {
projectKey,
encryptionKeys,
projectInfo: { name: 'Mapeo' },
roleName: ROLES[MEMBER_ROLE_ID].name,
invitorName: 'device0',
}
return r1.invite(peers[0].deviceId, invite)
}, 'invite fails')
})

inviteApi.on('invite-received', async ({ projectId }) => {
t.is(projectId, projectKeyToPublicId(projectKey), 'received invite')
await disconnect()
isMember = true
await inviteApi.accept(projectId)
t.pass()
})

const disconnect = replicate(r1, r2)
})

test('addProject throwing results in invite accept throwing', async (t) => {
t.plan(1)

Expand Down Expand Up @@ -548,7 +503,7 @@ test('Invite from multiple peers', async (t) => {
t.pass('One invitor did receive accept response')
t.is(response, LocalPeers.InviteResponse.ACCEPT, 'accept response')
} else {
t.is(response, LocalPeers.InviteResponse.ALREADY, 'already response')
t.is(response, LocalPeers.InviteResponse.REJECT, 'reject response')
}
})
replicate(invitee, invitor, { kp1: inviteeKeyPair, kp2: keyPair })
Expand Down Expand Up @@ -626,7 +581,7 @@ test.skip('Invite from multiple peers, first disconnects before accepted, receiv
t.pass('One invitor did receive accept response')
t.is(response, LocalPeers.InviteResponse.ACCEPT, 'accept response')
} else {
t.is(response, LocalPeers.InviteResponse.ALREADY, 'already response')
t.is(response, LocalPeers.InviteResponse.REJECT, 'reject response')
}
} catch (e) {
t.is(
Expand Down
29 changes: 0 additions & 29 deletions tests/local-peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,35 +229,6 @@ test('Invite to unknown peer', async (t) => {
)
})

test('Send invite and already on project', async (t) => {
t.plan(3)
const r1 = new LocalPeers()
const r2 = new LocalPeers()

const projectKey = Buffer.allocUnsafe(32).fill(0)

r1.on('peers', async (peers) => {
t.is(peers.length, 1)
const response = await r1.invite(peers[0].deviceId, {
projectKey,
encryptionKeys: { auth: randomBytes(32) },
roleName: ROLES[MEMBER_ROLE_ID].name,
invitorName: 'device0',
})
t.is(response, LocalPeers.InviteResponse.ALREADY)
})

r2.on('invite', (peerId, invite) => {
t.ok(invite.projectKey.equals(projectKey), 'invite project key correct')
r2.inviteResponse(peerId, {
projectKey: invite.projectKey,
decision: LocalPeers.InviteResponse.ALREADY,
})
})

replicate(r1, r2)
})

test('Send invite with encryption key', async (t) => {
t.plan(4)
const r1 = new LocalPeers()
Expand Down
Loading