diff --git a/src/components/BulkMembersDialog.vue b/src/components/BulkMembersDialog.vue
index dd41e474..412ade19 100644
--- a/src/components/BulkMembersDialog.vue
+++ b/src/components/BulkMembersDialog.vue
@@ -134,8 +134,9 @@ import { Vue, Component, Prop } from "vue-facing-decorator";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { SOMEONE_UNNAMED } from "@/constants/entities";
import { MemberData } from "@/interfaces";
-import { setVisibilityUtil, getHeaders } from "@/libs/endorserServer";
+import { setVisibilityUtil, getHeaders, register } from "@/libs/endorserServer";
import { createNotifyHelpers } from "@/utils/notify";
+import { Contact } from "@/db/tables/contacts";
@Component({
mixins: [PlatformServiceMixin],
@@ -253,33 +254,37 @@ export default class BulkMembersDialog extends Vue {
async handleMainAction() {
if (this.dialogType === "admit") {
- await this.admitWithVisibility();
+ await this.organizerAdmitAndAddWithVisibility();
} else {
- await this.addContactWithVisibility();
+ await this.memberAddContactWithVisibility();
}
}
- async admitWithVisibility() {
+ async organizerAdmitAndAddWithVisibility() {
try {
- const selectedMembers = this.membersData.filter((member) =>
+ const selectedMembers: MemberData[] = this.membersData.filter((member) =>
this.selectedMembers.includes(member.did),
);
- const notSelectedMembers = this.membersData.filter(
+ const notSelectedMembers: MemberData[] = this.membersData.filter(
(member) => !this.selectedMembers.includes(member.did),
);
let admittedCount = 0;
let contactAddedCount = 0;
+ let errors = 0;
for (const member of selectedMembers) {
try {
// First, admit the member
await this.admitMember(member);
+
+ // Register them
+ await this.registerMember(member);
admittedCount++;
// If they're not a contact yet, add them as a contact
if (!member.isContact) {
- await this.addAsContact(member);
+ await this.addAsContact(member, true);
contactAddedCount++;
}
@@ -289,19 +294,33 @@ export default class BulkMembersDialog extends Vue {
// eslint-disable-next-line no-console
console.error(`Error processing member ${member.did}:`, error);
// Continue with other members even if one fails
+ errors++;
}
}
// Show success notification
- this.$notify(
- {
- group: "alert",
- type: "success",
- title: "Members Admitted Successfully",
- text: `${admittedCount} member${admittedCount === 1 ? "" : "s"} admitted${contactAddedCount === 0 ? "" : admittedCount === contactAddedCount ? " and" : `, ${contactAddedCount}`}${contactAddedCount === 0 ? "" : ` added as contact${contactAddedCount === 1 ? "" : "s"}`}.`,
- },
- 10000,
- );
+ if (admittedCount > 0) {
+ this.$notify(
+ {
+ group: "alert",
+ type: "success",
+ title: "Members Admitted Successfully",
+ text: `${admittedCount} member${admittedCount === 1 ? "" : "s"} admitted and registered${contactAddedCount === 0 ? "" : admittedCount === contactAddedCount ? " and" : `, ${contactAddedCount}`}${contactAddedCount === 0 ? "" : ` added as contact${contactAddedCount === 1 ? "" : "s"}`}.`,
+ },
+ 10000,
+ );
+ }
+ if (errors > 0) {
+ this.$notify(
+ {
+ group: "alert",
+ type: "danger",
+ title: "Error",
+ text: "Failed to fully admit some members. Work with them individually below.",
+ },
+ 5000,
+ );
+ }
this.close(notSelectedMembers.map((member) => member.did));
} catch (error) {
@@ -312,19 +331,19 @@ export default class BulkMembersDialog extends Vue {
group: "alert",
type: "danger",
title: "Error",
- text: "Failed to admit some members. Please try again.",
+ text: "Some errors occurred. Work with members individually below.",
},
5000,
);
}
}
- async addContactWithVisibility() {
+ async memberAddContactWithVisibility() {
try {
- const selectedMembers = this.membersData.filter((member) =>
+ const selectedMembers: MemberData[] = this.membersData.filter((member) =>
this.selectedMembers.includes(member.did),
);
- const notSelectedMembers = this.membersData.filter(
+ const notSelectedMembers: MemberData[] = this.membersData.filter(
(member) => !this.selectedMembers.includes(member.did),
);
@@ -334,7 +353,7 @@ export default class BulkMembersDialog extends Vue {
try {
// If they're not a contact yet, add them as a contact first
if (!member.isContact) {
- await this.addAsContact(member);
+ await this.addAsContact(member, undefined);
contactsAddedCount++;
}
@@ -367,7 +386,7 @@ export default class BulkMembersDialog extends Vue {
group: "alert",
type: "danger",
title: "Error",
- text: "Failed to add some members as contacts. Please try again.",
+ text: "Some errors occurred. Work with members individually below.",
},
5000,
);
@@ -393,11 +412,39 @@ export default class BulkMembersDialog extends Vue {
}
}
- async addAsContact(member: { did: string; name: string }) {
+ async registerMember(member: MemberData) {
+ try {
+ const contact: Contact = { did: member.did };
+ const result = await register(
+ this.activeDid,
+ this.apiServer,
+ this.axios,
+ contact,
+ );
+ if (result.success) {
+ if (result.embeddedRecordError) {
+ throw new Error(result.embeddedRecordError);
+ }
+ await this.$updateContact(member.did, { registered: true });
+ } else {
+ throw result;
+ }
+ } catch (err) {
+ // eslint-disable-next-line no-console
+ console.error("Error registering member:", err);
+ throw err;
+ }
+ }
+
+ async addAsContact(
+ member: { did: string; name: string },
+ isRegistered?: boolean,
+ ) {
try {
- const newContact = {
+ const newContact: Contact = {
did: member.did,
name: member.name,
+ registered: isRegistered,
};
await this.$insertContact(newContact);
diff --git a/src/components/MembersList.vue b/src/components/MembersList.vue
index f0043040..d1b10567 100644
--- a/src/components/MembersList.vue
+++ b/src/components/MembersList.vue
@@ -99,7 +99,7 @@
+
+
+
+
+
+
+
+
(url, { jwtEncoded: vcJwt });
- if (resp.data?.success?.handleId) {
- return { success: true };
- } else if (resp.data?.success?.embeddedRecordError) {
+ if (resp.data?.success?.embeddedRecordError) {
let message =
"There was some problem with the registration and so it may not be complete.";
if (typeof resp.data.success.embeddedRecordError === "string") {
message += " " + resp.data.success.embeddedRecordError;
}
return { error: message };
+ } else if (resp.data?.success?.handleId) {
+ return { success: true };
} else {
- logger.error("Registration error:", JSON.stringify(resp.data));
- return { error: "Got a server error when registering." };
+ logger.error("Registration non-thrown error:", JSON.stringify(resp.data));
+ return {
+ error:
+ (resp.data?.error as { message?: string })?.message ||
+ (resp.data?.error as string) ||
+ "Got a server error when registering.",
+ };
}
} catch (error: unknown) {
if (error && typeof error === "object") {
const err = error as AxiosErrorResponse;
const errorMessage =
- err.message ||
- (err.response?.data &&
- typeof err.response.data === "object" &&
- "message" in err.response.data
- ? (err.response.data as { message: string }).message
- : undefined);
- logger.error("Registration error:", errorMessage || JSON.stringify(err));
+ err.response?.data?.error?.message ||
+ err.response?.data?.error ||
+ err.message;
+ logger.error(
+ "Registration thrown error:",
+ errorMessage || JSON.stringify(err),
+ );
return { error: errorMessage || "Got a server error when registering." };
}
return { error: "Got a server error when registering." };
diff --git a/src/views/ContactEditView.vue b/src/views/ContactEditView.vue
index 51687b5b..a3ec73ce 100644
--- a/src/views/ContactEditView.vue
+++ b/src/views/ContactEditView.vue
@@ -346,9 +346,7 @@ export default class ContactEditView extends Vue {
// Notify success and redirect
this.notify.success(NOTIFY_CONTACT_SAVED.message, TIMEOUTS.STANDARD);
- (this.$router as Router).push({
- path: "/did/" + encodeURIComponent(this.contact?.did || ""),
- });
+ this.$router.back();
}
}
diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue
index e31cb708..eebd8049 100644
--- a/src/views/ContactsView.vue
+++ b/src/views/ContactsView.vue
@@ -171,9 +171,11 @@ import {
CONTACT_IMPORT_ONE_URL_PATH_TIME_SAFARI,
CONTACT_URL_PATH_ENDORSER_CH_OLD,
} from "../libs/endorserServer";
-import { GiveSummaryRecord } from "@/interfaces/records";
-import { UserInfo } from "@/interfaces/common";
-import { VerifiableCredential } from "@/interfaces/claims-result";
+import {
+ GiveSummaryRecord,
+ UserInfo,
+ VerifiableCredential,
+} from "@/interfaces";
import * as libsUtil from "../libs/util";
import {
generateSaveAndActivateIdentity,
diff --git a/src/views/DIDView.vue b/src/views/DIDView.vue
index f6acf31c..8d67961c 100644
--- a/src/views/DIDView.vue
+++ b/src/views/DIDView.vue
@@ -12,20 +12,20 @@
-
-
+
-
-
+
@@ -476,7 +476,7 @@ export default class DIDView extends Vue {
* Navigation helper methods
*/
goBack() {
- this.$router.go(-1);
+ this.$router.back();
}
/**
diff --git a/src/views/OnboardMeetingSetupView.vue b/src/views/OnboardMeetingSetupView.vue
index e70148f5..33d345f0 100644
--- a/src/views/OnboardMeetingSetupView.vue
+++ b/src/views/OnboardMeetingSetupView.vue
@@ -473,6 +473,7 @@ export default class OnboardMeetingView extends Vue {
);
return;
}
+ const password: string = this.newOrUpdatedMeetingInputs.password;
// create content with user's name & DID encrypted with password
const content = {
@@ -482,7 +483,7 @@ export default class OnboardMeetingView extends Vue {
};
const encryptedContent = await encryptMessage(
JSON.stringify(content),
- this.newOrUpdatedMeetingInputs.password,
+ password,
);
const headers = await getHeaders(this.activeDid);
@@ -505,6 +506,11 @@ export default class OnboardMeetingView extends Vue {
this.newOrUpdatedMeetingInputs = null;
this.notify.success(NOTIFY_MEETING_CREATED.message, TIMEOUTS.STANDARD);
+ // redirect to the same page with the password parameter set
+ this.$router.push({
+ name: "onboard-meeting-setup",
+ query: { password: password },
+ });
} else {
throw { response: response };
}