Page MenuHomePhabricator

D12354.id41125.diff
No OneTemporary

D12354.id41125.diff

diff --git a/keyserver/src/creators/invite-link-creator.js b/keyserver/src/creators/invite-link-creator.js
--- a/keyserver/src/creators/invite-link-creator.js
+++ b/keyserver/src/creators/invite-link-creator.js
@@ -59,40 +59,61 @@
threadPermissions.MANAGE_INVITE_LINKS,
);
const existingPrimaryLinksPromise = fetchPrimaryInviteLinks(viewer);
+ const threadIDs = new Set([request.communityID]);
+ if (request.threadID) {
+ threadIDs.add(request.threadID);
+ }
const fetchThreadInfoPromise = fetchServerThreadInfos({
- threadID: request.communityID,
+ threadIDs,
});
const blobDownloadPromise = getInviteLinkBlob(request.name);
+ const canManageThreadLinksPromise = request.threadID
+ ? checkThreadPermission(
+ viewer,
+ request.threadID,
+ threadPermissions.MANAGE_INVITE_LINKS,
+ )
+ : false;
const [
hasPermission,
existingPrimaryLinks,
{ threadInfos },
blobDownloadResult,
+ canManageThreadLinks,
] = await Promise.all([
permissionPromise,
existingPrimaryLinksPromise,
fetchThreadInfoPromise,
blobDownloadPromise,
+ canManageThreadLinksPromise,
]);
- if (!hasPermission) {
+ if (!hasPermission || (request.threadID && !canManageThreadLinks)) {
throw new ServerError('invalid_credentials');
}
if (blobDownloadResult.found) {
throw new ServerError('already_in_use');
}
- const threadInfo = threadInfos[request.communityID];
- if (!threadInfo) {
- throw new ServerError('invalid_parameters');
- }
- const defaultRoleID = Object.keys(threadInfo.roles).find(
- roleID => threadInfo.roles[roleID].isDefault,
- );
- if (!defaultRoleID) {
- throw new ServerError('invalid_parameters');
+
+ const defaultRoleIDs: { [string]: string } = {};
+ for (const threadID of threadIDs) {
+ const threadInfo = threadInfos[threadID];
+ if (!threadInfo) {
+ throw new ServerError('invalid_parameters');
+ }
+ const defaultRoleID = Object.keys(threadInfo.roles).find(
+ roleID => threadInfo.roles[roleID].isDefault,
+ );
+ if (!defaultRoleID) {
+ throw new ServerError('invalid_parameters');
+ }
+ defaultRoleIDs[threadID] = defaultRoleID;
}
const existingPrimaryLink = existingPrimaryLinks.find(
- link => link.communityID === request.communityID && link.primary,
+ link =>
+ link.communityID === request.communityID &&
+ link.primary &&
+ (request.threadID ? link.threadID === request.threadID : !link.threadID),
);
const blobHolder = uuid.v4();
@@ -109,8 +130,14 @@
const query = SQL`
UPDATE invite_links
SET name = ${request.name}, blob_holder = ${blobHolder}
- WHERE \`primary\` = 1 AND community = ${request.communityID}
+ WHERE \`primary\` = 1 AND
+ community = ${request.communityID}
`;
+ if (request.threadID) {
+ query.append(SQL`AND thread = ${request.threadID}`);
+ } else {
+ query.append(SQL`AND thread IS NULL`);
+ }
try {
await dbQuery(query);
const holder = existingPrimaryLink.blobHolder;
@@ -139,7 +166,7 @@
return {
name: request.name,
primary: true,
- role: defaultRoleID,
+ role: defaultRoleIDs[request.communityID],
communityID: request.communityID,
expirationTime: null,
limitOfUses: null,
@@ -154,19 +181,28 @@
request.name,
true,
request.communityID,
- defaultRoleID,
+ defaultRoleIDs[request.communityID],
blobHolder,
+ request.threadID ?? null,
+ request.threadID ? defaultRoleIDs[request.threadID] : null,
];
const createLinkQuery = SQL`
- INSERT INTO invite_links(id, name, \`primary\`, community, role, blob_holder)
+ INSERT INTO invite_links(id, name, \`primary\`, community, role,
+ blob_holder, thread, thread_role)
SELECT ${row}
WHERE NOT EXISTS (
SELECT i.id
FROM invite_links i
WHERE i.\`primary\` = 1 AND i.community = ${request.communityID}
- )
`;
+ if (request.threadID) {
+ createLinkQuery.append(SQL`AND thread = ${request.threadID}`);
+ } else {
+ createLinkQuery.append(SQL`AND thread IS NULL`);
+ }
+ createLinkQuery.append(SQL`)`);
+
let result = null;
const deleteIDs = SQL`
DELETE FROM ids
@@ -208,7 +244,7 @@
return {
name: request.name,
primary: true,
- role: defaultRoleID,
+ role: defaultRoleIDs[request.communityID],
communityID: request.communityID,
expirationTime: null,
limitOfUses: null,
diff --git a/keyserver/src/fetchers/link-fetchers.js b/keyserver/src/fetchers/link-fetchers.js
--- a/keyserver/src/fetchers/link-fetchers.js
+++ b/keyserver/src/fetchers/link-fetchers.js
@@ -64,22 +64,33 @@
const query = SQL`
SELECT i.name, i.role, i.community, i.expiration_time AS expirationTime,
i.limit_of_uses AS limitOfUses, i.number_of_uses AS numberOfUses,
- i.\`primary\`, blob_holder AS blobHolder
+ i.\`primary\`, i.blob_holder AS blobHolder, i.thread,
+ i.thread_role AS threadRole
FROM invite_links i
`;
query.append(condition);
const [result] = await dbQuery(query);
- return result.map(row => ({
- name: row.name,
- primary: row.primary === 1,
- role: row.role.toString(),
- communityID: row.community.toString(),
- expirationTime: row.expirationTime,
- limitOfUses: row.limitOfUses,
- numberOfUses: row.numberOfUses,
- blobHolder: row.blobHolder,
- }));
+ return result.map(row => {
+ const link = {
+ name: row.name,
+ primary: row.primary === 1,
+ role: row.role.toString(),
+ communityID: row.community.toString(),
+ expirationTime: row.expirationTime,
+ limitOfUses: row.limitOfUses,
+ numberOfUses: row.numberOfUses,
+ blobHolder: row.blobHolder,
+ };
+ if (row.thread && row.threadRole) {
+ return {
+ ...link,
+ threadID: row.thread.toString(),
+ threadRole: row.threadRole.toString(),
+ };
+ }
+ return link;
+ });
}
function fetchPrimaryInviteLinks(
diff --git a/keyserver/src/responders/link-responders.js b/keyserver/src/responders/link-responders.js
--- a/keyserver/src/responders/link-responders.js
+++ b/keyserver/src/responders/link-responders.js
@@ -48,6 +48,7 @@
tShape<CreateOrUpdatePublicLinkRequest>({
name: t.String,
communityID: tID,
+ threadID: t.maybe(tID),
});
async function createOrUpdatePublicLinkResponder(
diff --git a/lib/types/link-types.js b/lib/types/link-types.js
--- a/lib/types/link-types.js
+++ b/lib/types/link-types.js
@@ -28,6 +28,8 @@
+expirationTime: ?number,
+limitOfUses: ?number,
+numberOfUses: number,
+ +threadID?: string,
+ +threadRole?: string,
};
export type InviteLinkWithHolder = $ReadOnly<{
@@ -43,6 +45,8 @@
expirationTime: t.maybe(t.Number),
limitOfUses: t.maybe(t.Number),
numberOfUses: t.Number,
+ threadID: t.maybe(tID),
+ threadRole: t.maybe(tID),
});
export type FetchInviteLinksResponse = {
@@ -73,6 +77,7 @@
export type CreateOrUpdatePublicLinkRequest = {
+name: string,
+communityID: string,
+ +threadID?: string,
};
export type DisableInviteLinkRequest = {

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 2:30 PM (19 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2579712
Default Alt Text
D12354.id41125.diff (7 KB)

Event Timeline