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

Inviting unregistered users by email #6901

Merged
merged 71 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
a902db3
draft invitation
klakhov Sep 26, 2023
6c8e5fb
sendmail on invite
klakhov Sep 26, 2023
55c47e7
updated message
klakhov Sep 26, 2023
705f9f1
added basic inv serializer, fixed membership creation
klakhov Sep 26, 2023
5b519db
removed lots of requests for invitations
klakhov Sep 26, 2023
5a3bb43
update invitaiton link
klakhov Sep 26, 2023
ebd98b9
added register from invitation page
klakhov Sep 26, 2023
464b814
added accept invitation form
klakhov Sep 26, 2023
499c187
added mock server accept endpoint
klakhov Sep 26, 2023
768b9a8
added sent date field
klakhov Sep 27, 2023
a94e247
updated UI register data type
klakhov Sep 27, 2023
f3aa0e4
added user setup on accept
klakhov Sep 27, 2023
4cbf36a
updated invitation messages
klakhov Sep 27, 2023
7347746
refactore accept endpoint
klakhov Sep 27, 2023
4b63507
returned auto accept for existing users
klakhov Sep 27, 2023
1d97f80
added resend endpoint
klakhov Sep 27, 2023
2ba490f
updated invitation settings
klakhov Sep 27, 2023
f65494a
activate organization after invite on login
klakhov Sep 28, 2023
f3b1f41
typed ui membership and invitation
klakhov Sep 28, 2023
5a119c6
added resend/delete cvat-core methods
klakhov Sep 28, 2023
8735802
added invitation resend/delete actions
klakhov Sep 28, 2023
b27c315
added resend, delete buttons
klakhov Sep 28, 2023
b932980
delete membeship with invitation
klakhov Sep 28, 2023
9881a41
Merge branch 'develop' into kl/invite-users
klakhov Sep 29, 2023
945fcff
added ui error handling
klakhov Sep 29, 2023
1f9761b
added info notification
klakhov Sep 29, 2023
9e576b3
removed comment
klakhov Sep 29, 2023
d7ed980
added checks
klakhov Sep 29, 2023
a57fed7
removed excessive file
klakhov Oct 2, 2023
1ba5703
Merge branch 'develop' into kl/invite-users
klakhov Oct 2, 2023
3d5e38a
updated schema
klakhov Oct 2, 2023
4e14ed2
fixed https link
klakhov Oct 2, 2023
8b6ac0b
updated email template
klakhov Oct 2, 2023
dc37453
added comma
klakhov Oct 2, 2023
d46c9f6
updated setting name
klakhov Oct 2, 2023
b804641
updated email subject
klakhov Oct 2, 2023
2e4a396
removed valiidate username
klakhov Oct 2, 2023
89c3c62
added success info message
klakhov Oct 2, 2023
d8f88f2
updated setting
klakhov Oct 2, 2023
a41d969
removed excessive check
klakhov Oct 2, 2023
c03f114
changed action button
klakhov Oct 2, 2023
be249c6
added transaction
klakhov Oct 2, 2023
1fa4834
updated imports
klakhov Oct 2, 2023
8dec73f
updated schema
klakhov Oct 2, 2023
6f82fea
throw explicit error if email backend is not configured
klakhov Oct 5, 2023
c0e05f0
removed rawuser, keep only serialized user
klakhov Oct 5, 2023
89aef3e
fixed memberships results
klakhov Oct 5, 2023
19dce0d
moved accept invitation to oranization namespace
klakhov Oct 5, 2023
9b56f05
updated email template
klakhov Oct 5, 2023
11114ce
removed delete invitation
klakhov Oct 5, 2023
74a9a73
fixed typo
klakhov Oct 5, 2023
92d0e70
renamed disable navigation
klakhov Oct 5, 2023
e0bedaf
removed accept organization param
klakhov Oct 5, 2023
93a818b
fixed tag in template
klakhov Oct 5, 2023
74ddfdc
fixed owner null
klakhov Oct 5, 2023
cb6bbaf
updated schema
klakhov Oct 6, 2023
aec2763
updated tests db
klakhov Oct 6, 2023
0910c8d
fixed schema version
klakhov Oct 6, 2023
c720b57
Merge branch 'develop' into kl/invite-users
klakhov Oct 9, 2023
faf4ace
updated package versions & changelog
klakhov Oct 9, 2023
47343de
added newline
klakhov Oct 9, 2023
7f5667c
Merge branch 'develop' into kl/invite-users
nmanovic Oct 9, 2023
cd86e3a
updated accept invitation serializer
klakhov Oct 9, 2023
2acb932
updated status code & fixed typo
klakhov Oct 9, 2023
c30588f
reverted invitation field
klakhov Oct 10, 2023
0627576
return object instead of string
klakhov Oct 10, 2023
852bb54
updated ui to object response
klakhov Oct 10, 2023
8676f6e
Merge branch 'develop' into kl/invite-users
klakhov Oct 10, 2023
eeea945
reverted test assets
klakhov Oct 10, 2023
5b59af8
Merge branch 'develop' into kl/invite-users
klakhov Oct 11, 2023
2814477
Merge branch 'develop' into kl/invite-users
nmanovic Oct 13, 2023
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
22 changes: 22 additions & 0 deletions cvat-core/src/api-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ export default function implementAPI(cvat) {
await serverProxy.server.resetPassword(newPassword1, newPassword2, uid, token);
};

cvat.server.acceptInvitation.implementation = async (
username,
firstName,
lastName,
email,
password,
userConfirmations,
key,
) => {
const orgSlug = await serverProxy.server.acceptInvitation(
username,
firstName,
lastName,
email,
password,
userConfirmations,
key,
);

return orgSlug;
};
klakhov marked this conversation as resolved.
Show resolved Hide resolved

cvat.server.authorized.implementation = async () => {
const result = await serverProxy.server.authorized();
return result;
Expand Down
13 changes: 13 additions & 0 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ function build() {
);
return result;
},
async acceptInvitation(username, firstName, lastName, email, password, userConfirmations, key) {
const result = await PluginRegistry.apiWrapper(
cvat.server.acceptInvitation,
username,
firstName,
lastName,
email,
password,
userConfirmations,
key,
);
return result;
},
async authorized() {
const result = await PluginRegistry.apiWrapper(cvat.server.authorized);
return result;
Expand Down
146 changes: 121 additions & 25 deletions cvat-core/src/organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,84 @@ import { MembershipRole } from './enums';
import { ArgumentError, DataError } from './exceptions';
import PluginRegistry from './plugins';
import serverProxy from './server-proxy';
import User from './user';
import User, { RawUserData } from './user';

interface Membership {
user: User;
interface SerializedInvitationData {
created_date: string;
key: string;
owner: RawUserData;
}

interface SerializedMembershipData {
id: number;
user: RawUserData;
is_active: boolean;
joined_date: string;
role: MembershipRole;
invitation: {
created_date: string;
owner: User;
} | null;
invitation: SerializedInvitationData | null;
}

export class Invitation {
#createdDate: string;
#owner: User;
#key: string;

constructor(initialData: SerializedInvitationData) {
this.#createdDate = initialData.created_date;
this.#owner = new User(initialData.owner);
this.#key = initialData.key;
}

get owner(): User {
return this.#owner;
}

get createdDate(): string {
return this.#createdDate;
}

get key(): string {
return this.#key;
}
}

export class Membership {
#id: number;
#user: User;
#isActive: boolean;
#joinedDate: string;
#role: MembershipRole;
#invitation: Invitation | null;

constructor(initialData: SerializedMembershipData) {
this.#id = initialData.id;
this.#user = new User(initialData.user);
this.#isActive = initialData.is_active;
this.#joinedDate = initialData.joined_date;
this.#role = initialData.role;
this.#invitation = initialData.invitation ? new Invitation(initialData.invitation) : null;
}

get id(): number {
return this.#id;
}

get user(): User {
return this.#user;
}

get isActive(): boolean {
return this.#isActive;
}
get joinedDate(): string {
return this.#joinedDate;
}
get role(): MembershipRole {
return this.#role;
}
get invitation(): Invitation {
return this.#invitation;
}
}

export default class Organization {
Expand Down Expand Up @@ -193,6 +260,24 @@ export default class Organization {
);
return result;
}

public async resendInvitation(key: string): Promise<void> {
const result = await PluginRegistry.apiWrapper.call(
this,
Organization.prototype.resendInvitation,
key,
);
return result;
}

public async deleteInvitation(key: string): Promise<void> {
const result = await PluginRegistry.apiWrapper.call(
this,
Organization.prototype.deleteInvitation,
key,
);
return result;
}
}

Object.defineProperties(Organization.prototype.save, {
Expand Down Expand Up @@ -234,24 +319,9 @@ Object.defineProperties(Organization.prototype.members, {
checkObjectType('pageSize', pageSize, 'number');

const result = await serverProxy.organizations.members(orgSlug, page, pageSize);
await Promise.all(
result.results.map((membership) => {
const { invitation } = membership;
membership.user = new User(membership.user);
if (invitation) {
return serverProxy.organizations
.invitation(invitation)
.then((invitationData) => {
membership.invitation = invitationData;
})
.catch(() => {
membership.invitation = null;
});
}

return Promise.resolve();
}),
);
result.results = result.results.map((rawMembership: SerializedMembershipData) => new Membership(
rawMembership,
));
klakhov marked this conversation as resolved.
Show resolved Hide resolved

result.results.count = result.count;
return result.results;
Expand Down Expand Up @@ -347,3 +417,29 @@ Object.defineProperties(Organization.prototype.leave, {
},
},
});

Object.defineProperties(Organization.prototype.resendInvitation, {
implementation: {
writable: false,
enumerable: false,
value: async function implementation(key: string) {
checkObjectType('key', key, 'string');
if (typeof this.id === 'number') {
await serverProxy.organizations.resendInvitation(key);
}
},
},
});

Object.defineProperties(Organization.prototype.deleteInvitation, {
implementation: {
writable: false,
enumerable: false,
value: async function implementation(key: string) {
checkObjectType('key', key, 'string');
if (typeof this.id === 'number') {
await serverProxy.organizations.deleteInvitation(key);
}
},
},
});
48 changes: 48 additions & 0 deletions cvat-core/src/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,33 @@ async function resetPassword(newPassword1: string, newPassword2: string, uid: st
}
}

async function acceptInvitation(
username: string,
firstName: string,
lastName: string,
email: string,
password: string,
confirmations: Record<string, string>,
key: string,
): Promise<SerializedRegister> {
let response = null;

try {
response = await Axios.post(`${config.backendAPI}/invitations/${key}/accept`, {
username,
first_name: firstName,
last_name: lastName,
password1: password,
password2: password,
confirmations,
});
} catch (errorData) {
throw generateError(errorData);
}

return response.data;
}

async function getSelf(): Promise<SerializedUser> {
const { backendAPI } = config;

Expand Down Expand Up @@ -2059,6 +2086,24 @@ async function inviteOrganizationMembers(orgId, data) {
}
}

async function resendOrganizationInvitation(key) {
const { backendAPI } = config;
try {
await Axios.post(`${backendAPI}/invitations/${key}/resend`);
} catch (errorData) {
throw generateError(errorData);
}
}

async function deleteOrganizationInvitation(key) {
const { backendAPI } = config;
try {
await Axios.delete(`${backendAPI}/invitations/${key}`);
} catch (errorData) {
throw generateError(errorData);
}
}

async function updateOrganizationMembership(membershipId, data) {
const { backendAPI } = config;
let response = null;
Expand Down Expand Up @@ -2365,6 +2410,7 @@ export default Object.freeze({
request: serverRequest,
userAgreements,
installedApps,
acceptInvitation,
}),

projects: Object.freeze({
Expand Down Expand Up @@ -2481,6 +2527,8 @@ export default Object.freeze({
invitation: getMembershipInvitation,
delete: deleteOrganization,
invite: inviteOrganizationMembers,
resendInvitation: resendOrganizationInvitation,
deleteInvitation: deleteOrganizationInvitation,
updateMembership: updateOrganizationMembership,
deleteMembership: deleteOrganizationMembership,
}),
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT

interface RawUserData {
export interface RawUserData {
klakhov marked this conversation as resolved.
Show resolved Hide resolved
id: number;
username: string;
email: string;
Expand Down
Loading
Loading