-
Notifications
You must be signed in to change notification settings - Fork 87
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
ref: migrate transfer ownership flow to TypeScript #718
Merged
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
49fb60d
feat(FormModel): update transferOwner instance method to return itself
karrui dbfbabb
feat(FormModel): remove currentOwner parameter from Form#transferOwner
karrui 0765cd9
feat(FormModel): remove autogenerated id on permissionList objects
karrui 2500701
test(FormModel): move getDashboardForms into correct static desc block
karrui 46a5372
test(FormModel): add tests for transferOwner instance method
karrui 0384444
feat(AdminFormSvc): add transferFormOwnership fn
karrui ffea92c
test(AdminFormSvc): add tests for transferFormOwnership
karrui 40027e6
feat(AdminFormCtl): add handleTransferFormOwnership handler fn
karrui b1799df
feat(AdminFormRoutes): use new controller fn for transferring owner
karrui 59d54c4
test(AdminFormCtl): add tests for handleTransferFormOwnership
karrui bb7b8b4
feat: remove old transferOwner function
karrui 42446cd
feat(FormModel): add tighter pre-validate hook for form schema
karrui 7d8a7a0
test(FormModel): add tests for increased validation impl
karrui e9e26cb
feat(FormModel): reduce responsibilities of transferOwner method
karrui e5ebe51
test(UserService): add missing tests for findAdminById
karrui baf06f9
feat(UserSvc): add findAdminByEmail fn (and tests)
karrui 847df8d
feat(AdminFormSvc): move transfer ownership checks into service fn
karrui a86349a
test(AdminFormSvc): update tests for transferFormOwnership
karrui dd8a336
feat(FormModel): restore _id generation for permissionList
karrui 9c11b20
feat(AdminFormSvc): return TransferOwnershipError on missing new owner
karrui b7742c4
ref: rename findAdminBy* to findUserBy*
karrui be3c617
Merge branch 'develop' into ref/transfer-ownership
karrui 5beffd9
feat(AdminFormSvc): move ownerEmail equality check up one step
karrui 3ffc43f
feat: change transfer ownership error return 400
karrui 0cf974e
Merge branch 'develop' into ref/transfer-ownership
karrui f52126e
Merge branch 'develop' into ref/transfer-ownership
karrui 361bb58
ref(FormModel): rename getDashboardForms to getAllByUserIdOrEmail
karrui 281b542
ref(FormModel): re-renaming to getMetaByUserIdOrEmail
karrui File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
import BSON from 'bson-ext' | ||
import { compact, filter, pick, uniq } from 'lodash' | ||
import { Mongoose, Schema, SchemaOptions } from 'mongoose' | ||
import { compact, pick, uniq } from 'lodash' | ||
import mongoose, { Mongoose, Schema, SchemaOptions } from 'mongoose' | ||
import validator from 'validator' | ||
|
||
import { | ||
AuthType, | ||
BasicField, | ||
Colors, | ||
DashboardFormView, | ||
FormLogoState, | ||
FormMetaView, | ||
FormOtpData, | ||
IEmailFormModel, | ||
IEmailFormSchema, | ||
|
@@ -443,26 +443,16 @@ const compileFormModel = (db: Mongoose): IFormModel => { | |
} | ||
|
||
// Transfer ownership of the form to another user | ||
FormSchema.methods.transferOwner = async function ( | ||
currentOwner: IUserSchema, | ||
newOwnerEmail: string, | ||
) { | ||
// Verify that the new owner exists | ||
const newOwner = await User.findOne({ email: newOwnerEmail }) | ||
if (newOwner == null) { | ||
throw new Error( | ||
`${newOwnerEmail} must have logged in once before being added as Owner`, | ||
) | ||
} | ||
|
||
// Update form's admin to new owner's id | ||
FormSchema.methods.transferOwner = async function (currentOwner, newOwner) { | ||
// Update form's admin to new owner's id. | ||
this.admin = newOwner._id | ||
|
||
// Remove new owner from perm list and include previous owner as an editor | ||
this.permissionList = filter(this.permissionList, (item) => { | ||
return item.email !== newOwnerEmail | ||
}) | ||
// Remove new owner from perm list and include previous owner as an editor. | ||
this.permissionList = | ||
this.permissionList?.filter((item) => item.email !== newOwner.email) ?? [] | ||
this.permissionList.push({ email: currentOwner.email, write: true }) | ||
|
||
return this.save() | ||
} | ||
|
||
// Statics | ||
|
@@ -520,11 +510,11 @@ const compileFormModel = (db: Mongoose): IFormModel => { | |
return form.save() | ||
} | ||
|
||
FormSchema.statics.getDashboardForms = async function ( | ||
FormSchema.statics.getMetaByUserIdOrEmail = async function ( | ||
this: IFormModel, | ||
userId: IUserSchema['_id'], | ||
userEmail: IUserSchema['email'], | ||
): Promise<DashboardFormView[]> { | ||
): Promise<FormMetaView[]> { | ||
return ( | ||
this.find() | ||
// List forms when either the user is an admin or collaborator. | ||
|
@@ -562,8 +552,19 @@ const compileFormModel = (db: Mongoose): IFormModel => { | |
// Validate that admin exists before form is created. | ||
return User.findById(this.admin).then((admin) => { | ||
if (!admin) { | ||
throw new Error(`Admin for this form is not found.`) | ||
const validationError = this.invalidate( | ||
'admin', | ||
'Admin for this form is not found.', | ||
) as mongoose.Error.ValidationError | ||
return next(validationError) | ||
Comment on lines
+555
to
+559
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice use of |
||
} | ||
|
||
// Remove admin from the permission list if they exist. | ||
// This prevents the form owner from being both an admin and another role. | ||
this.permissionList = this.permissionList?.filter( | ||
(item) => item.email !== admin.email, | ||
) | ||
|
||
return next() | ||
}) | ||
}) | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did we ever figure out if a default value would be provided by mongoose on read, if it wasn't present in the DB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, will automatically have an empty array: https://mongoosejs.com/docs/schematypes.html#arrays
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this should be safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript will complain, but that is because it is optional in the schema. Will probably make a
IFormDocument
type that has all the default optionals populated as required to avoid this then.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll do the retyping in a separate PR to avoid polluting this even more