Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@itleadopencommerce/api-plugin-accounts

Package Overview
Dependencies
Maintainers
5
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@itleadopencommerce/api-plugin-accounts - npm Package Compare versions

Comparing version 2.16.2 to 2.16.3

src/util/checkLogin.js

5

package.json
{
"name": "@itleadopencommerce/api-plugin-accounts",
"description": "Accounts plugin for the Reaction API",
"version": "2.16.2",
"version": "2.16.3",
"main": "index.js",

@@ -37,4 +37,3 @@ "type": "module",

"lodash": "^4.17.15",
"simpl-schema": "^1.8.0",
"ramda": "^0.27.1"
"simpl-schema": "^1.8.0"
},

@@ -41,0 +40,0 @@ "devDependencies": {

@@ -30,9 +30,2 @@ # api-plugin-accounts

## Version control
### v2.16.2
#### Summary
- Remove possibility to remove the last one addressBook for profile
- add validatePermissions for updateAccount(), addAddressBook(), updateAccount(), updateAccountAddressBookEntry()
#### Deprecated
- checkLogin()
### v2.16.0

@@ -39,0 +32,0 @@ #### Deprecated

2

src/index.js

@@ -13,3 +13,2 @@ import pkg from "../package.json";

import { Account, Group, Profile, Impersonation } from "./simpleSchemas.js";
import { getPermissionForPluginAccounts } from "./util/permissionForPluginAccounts";

@@ -30,3 +29,2 @@ /**

startup: [afterShopCreate],
getHasPermissionFunctionForUser: [getPermissionForPluginAccounts],
},

@@ -33,0 +31,0 @@ collections: {

@@ -5,6 +5,2 @@ import SimpleSchema from "simpl-schema";

const inputUpdateAccount = new SimpleSchema({
accountId: {
type: String,
optional: true,
},
bio: {

@@ -11,0 +7,0 @@ type: String,

import Random from "@reactioncommerce/random";
import ReactionError from "@reactioncommerce/reaction-error";
import { AccountProfileAddress } from "../simpleSchemas";
import setDefaultsAddressBook from "../util/setDefaultsAddressBook";
import checkLogin from "../util/checkLogin";
/**

@@ -15,39 +14,61 @@ * @name accounts/addressBookAdd

*/
export default async function addAddressBook(context, input) {
const { address, accountId: requestedAccountId } = input;
const { appEvents, collections, accountId: contextAccountId } = context;
export default async function addAddressBook(context, { address }) {
await checkLogin(context);
if (!address.isBillingDefault) Object.assign(address, {isBillingDefault: false});
if (!address.isCommercial) Object.assign(address, {isCommercial: false});
if (!address.isShippingDefault) Object.assign(address, {isShippingDefault: false});
const { appEvents, collections, accountId: userId } = context;
const { Accounts } = collections;
const accountId = requestedAccountId || contextAccountId;
const selector = { _id: accountId };
await context.validatePermissions("permissionForPluginAccounts", "reaction:legacy:accounts/add:address-books", {
subjectAccountId: accountId,
});
// TODO add backdoor to change address books by admin
if (!address.isBillingDefault) Object.assign(address, { isBillingDefault: false });
if (!address.isCommercial) Object.assign(address, { isCommercial: false });
if (!address.isShippingDefault) Object.assign(address, { isShippingDefault: false });
// required default ID
if (!address._id) address._id = Random.id();
// if address got shipment or billing default, we need to update cart
// addresses accordingly
if (address.isShippingDefault || address.isBillingDefault) {
// then change the address that has been affected
if (address.isShippingDefault) {
await Accounts.updateMany({
userId,
"profile.addressBook.isShippingDefault": true
}, {
$set: {
"profile.addressBook.$.isShippingDefault": false
}
});
}
if (address.isBillingDefault) {
await Accounts.updateMany({
userId,
"profile.addressBook.isBillingDefault": true
}, {
$set: {
"profile.addressBook.$.isBillingDefault": false
}
});
}
}
// validate input by schema
AccountProfileAddress.validate(address);
// if address got shipment or billing default, we need to update cart
// addresses accordingly
// then change the address that has been affected
await setDefaultsAddressBook(context, {
isShippingDefault: address.isShippingDefault,
isBillingDefault: address.isBillingDefault,
accountId,
});
const { value: updatedAccount } = await Accounts.findOneAndUpdate(
selector,
{ userId },
{
$addToSet: { "profile.addressBook": address },
$set: { updatedAt: new Date() },
$addToSet: {
"profile.addressBook": address
},
$set: {
updatedAt: new Date()
}
},
{ returnOriginal: false },
{
returnOriginal: false
}
);

@@ -61,3 +82,3 @@

account: updatedAccount,
updatedBy: contextAccountId,
updatedBy: userId,
updatedFields: ["profile.addressBook"]

@@ -64,0 +85,0 @@ });

@@ -5,7 +5,4 @@ import SimpleSchema from "simpl-schema";

const inputSchema = new SimpleSchema({
accountId: {
type: String,
optional: true,
},
addressId: String,
accountId: String,
addressId: String
});

@@ -25,15 +22,15 @@

inputSchema.validate(input);
const { appEvents, collections, userId: userIdFromContext } = context;
const { Accounts } = collections;
const {
accountId,
addressId
} = input;
const { addressId, accountId: requestedAccountId } = input;
const { appEvents, collections, accountId: contextAccountId } = context;
const { Accounts } = collections;
const accountId = requestedAccountId || contextAccountId;
const selector = { _id: accountId };
await context.validatePermissions("permissionForPluginAccounts", "reaction:legacy:accounts/remove:address-books", {
subjectAccountId: accountId
const account = await Accounts.findOne({ _id: accountId });
if (!account) throw new ReactionError("not-found", "Not Found");
await context.validatePermissions(`reaction:legacy:accounts:${account._id}`, "remove:address-books", {
owner: account.userId
});
const account = await Accounts.findOne(selector);
if (!account) throw new ReactionError("not-found", "The Account doesn`t exist");

@@ -43,19 +40,23 @@ const addressBeingRemoved = account.profile && Array.isArray(account.profile.addressBook) &&

if (!addressBeingRemoved) throw new ReactionError("not-found", "Address Not Found");
if (account.profile.addressBook.length === 1)
throw new ReactionError("not-found", "Can`t remove the last one addressBook");
const { value: updatedAccount } = await Accounts.findOneAndUpdate({
...selector,
"profile.addressBook._id": addressId
},
{ $pull: { "profile.addressBook": { _id: addressId } } },
{ returnOriginal: false }
);
"_id": accountId,
"profile.addressBook._id": addressId
}, {
$pull: {
"profile.addressBook": {
_id: addressId
}
}
}, {
returnOriginal: false
});
if (!updatedAccount)
if (!updatedAccount) {
throw new ReactionError("server-error", "Unable to remove address from account");
}
await appEvents.emit("afterAccountUpdate", {
account: updatedAccount,
updatedBy: contextAccountId,
updatedBy: userIdFromContext
});

@@ -62,0 +63,0 @@

@@ -6,3 +6,110 @@ import ReactionError from "@reactioncommerce/reaction-error";

import inputUpdateAccount from "../inputSchemas/inputUpdateAccount.js";
import checkLogin from "../util/checkLogin.js";
const Company = new SimpleSchema({
country: {
type: String,
optional: true,
},
name: {
type: String,
optional: true,
},
address: {
type: String,
optional: true,
},
phone: {
type: String,
optional: true,
},
city: {
type: String,
optional: true,
},
state: {
type: String,
optional: true,
},
tin: {
type: String,
optional: true,
},
type: {
type: String,
optional: true,
},
site: {
type: String,
optional: true,
},
});
const inputSchema = new SimpleSchema({
accountId: {
type: String,
optional: true,
},
bio: {
type: String,
optional: true,
},
currencyCode: {
type: String,
optional: true,
},
firstName: {
type: String,
optional: true,
},
language: {
type: String,
optional: true,
},
lastName: {
type: String,
optional: true,
},
name: {
type: String,
optional: true,
},
status: {
type: String,
optional: true,
},
company: {
type: Company,
optional: true,
},
note: {
type: String,
optional: true,
},
picture: {
type: String,
optional: true,
},
username: {
type: String,
optional: true,
},
termAndConditions: {
type: Boolean,
},
isAdult: {
type: Boolean,
optional: true,
},
personalDataToOtherCompanies: {
type: Boolean,
optional: true,
},
personalDataToPromotionalOffers: {
type: Boolean,
optional: true,
},
});
/**

@@ -23,26 +130,52 @@ * @name accounts/updateAccount

export default async function updateAccount(context, input) {
await checkLogin(context);
inputUpdateAccount.validate(input);
const { appEvents, collections, accountId: contextAccountId } = context;
const { appEvents, collections, accountId } = context;
const { Accounts } = collections;
const {
bio, address, currencyCode, firstName, language,
lastName, name, note, status, picture, username,
termAndConditions, isAdult, birthday,
personalDataToOtherCompanies, personalDataToPromotionalOffers,
accountId: requestedAccountId,
bio,
address,
currencyCode,
firstName,
language,
lastName,
name,
note,
status,
company,
picture,
username,
termAndConditions,
isAdult,
birthday,
personalDataToOtherCompanies,
personalDataToPromotionalOffers,
} = input;
// TODO
// it is more better to build requested permission on data we want to change.
// In that case we check permission for all changes -> [update:email, update:phone, ...]
await context.validatePermissions("permissionForPluginAccounts", "reaction:legacy:accounts/update", {
subjectAccountId: requestedAccountId || contextAccountId,
});
if (!accountId) throw new ReactionError("access-denied", "Access Denied");
// we ask change personl data for another account if we have enought permission level
const selector = { _id: requestedAccountId || contextAccountId };
const account = await Accounts.findOne(selector);
const account = await Accounts.findOne(
{ _id: accountId },
{ projection: { userId: 1 } }
);
if (!account) throw new ReactionError("not-found", "No account found");
await context.validatePermissions(
`reaction:legacy:accounts:${accountId}`,
"update",
{
owner: account.userId,
}
);
// TODO Rebuild plugin-core and fix validatePermissions func
// await context.validatePermissions(
// `reaction:legacy:accounts:${accountId}`,
// "update",
// { owner: accountId }
// );
const updates = {};

@@ -52,4 +185,8 @@ const updatedFields = [];

if (typeof currencyCode === "string" || currencyCode === null) {
if (currencyCode !== null && !CurrencyDefinitions[currencyCode])
throw new ReactionError("invalid-argument", `No currency has code "${currencyCode}"`);
if (currencyCode !== null && !CurrencyDefinitions[currencyCode]) {
throw new ReactionError(
"invalid-argument",
`No currency has code "${currencyCode}"`
);
}

@@ -65,2 +202,7 @@ updates["profile.currency"] = currencyCode;

if (typeof company === "object" || company === null) {
updates.company = company;
updatedFields.push("company");
}
if (typeof lastName === "string" || lastName === null) {

@@ -97,3 +239,3 @@ updates["profile.lastName"] = lastName;

if (typeof picture === "string") {
if (typeof picture === "string" || picture === null) {
updates["profile.picture"] = picture;

@@ -103,3 +245,3 @@ updatedFields.push("picture");

if (typeof username === "string") {
if (typeof username === "string" || username === null) {
updates.username = username;

@@ -110,3 +252,3 @@ updates["profile.username"] = username;

if (typeof termAndConditions === "boolean") {
if (typeof termAndConditions === "boolean" || termAndConditions === null) {
updates["termAndConditions"] = termAndConditions;

@@ -116,3 +258,3 @@ updatedFields.push("termAndConditions");

if (typeof isAdult === "boolean") {
if (typeof isAdult === "boolean" || isAdult === null) {
updates["isAdult"] = isAdult;

@@ -122,3 +264,6 @@ updatedFields.push("isAdult");

if (typeof personalDataToOtherCompanies === "boolean") {
if (
typeof personalDataToOtherCompanies === "boolean" ||
personalDataToOtherCompanies === null
) {
updates["personalDataToOtherCompanies"] = personalDataToOtherCompanies;

@@ -128,4 +273,8 @@ updatedFields.push("personalDataToOtherCompanies");

if (typeof personalDataToPromotionalOffers === "boolean") {
updates["personalDataToPromotionalOffers"] = personalDataToPromotionalOffers;
if (
typeof personalDataToPromotionalOffers === "boolean" ||
personalDataToPromotionalOffers === null
) {
updates["personalDataToPromotionalOffers"] =
personalDataToPromotionalOffers;
updatedFields.push("personalDataToPromotionalOffers");

@@ -162,3 +311,3 @@ }

const { value: updatedAccount } = await Accounts.findOneAndUpdate(
selector,
{ userId: accountId },
modifier,

@@ -170,3 +319,3 @@ { returnOriginal: false }

account: updatedAccount,
updatedBy: contextAccountId,
updatedBy: accountId,
updatedFields,

@@ -173,0 +322,0 @@ });

import SimpleSchema from "simpl-schema";
import ReactionError from "@reactioncommerce/reaction-error";
import { AccountProfileAddress } from "../simpleSchemas.js";
import checkLogin from "../util/checkLogin.js";
const inputSchema = new SimpleSchema({
address: AccountProfileAddress,
accountId: {
type: {
type: String,

@@ -24,38 +25,52 @@ optional: true,

export default async function updateAccountAddressBookEntry(context, input) {
const { address, accountId: requestedAccountId } = input;
await checkLogin(context);
const { address, type } = input;
if (!address.isBillingDefault) Object.assign(address, { isBillingDefault: false });
if (!address.isCommercial) Object.assign(address, { isCommercial: false });
if (!address.isShippingDefault) Object.assign(address, { isShippingDefault: false });
inputSchema.validate(input);
const { appEvents, collections, accountId: contextAccountId } = context;
const { appEvents, collections, accountId: userId } = context;
const { Accounts } = collections;
const accountId = requestedAccountId || contextAccountId;
const selector = { _id: accountId };
await context.validatePermissions("permissionForPluginAccounts", "reaction:legacy:accounts/update:address-books", {
subjectAccountId: accountId,
});
const account = await Accounts.findOne({ userId });
const account = await Accounts.findOne(selector);
if (!account) throw new ReactionError("not-found", "The Account doesn`t exist");
// TODO add backdoor to change address books by admin
// Make sure address exists before trying to update
const oldAddress = (account?.profile?.addressBook || []).find((addr) => addr._id === address._id);
if (!oldAddress) throw new ReactionError("not-found", "The AddressBook with provided id doesn`t exist");
const oldAddress = (account.profile.addressBook || []).find(
(addr) => addr._id === address._id
);
if (!oldAddress)
throw new ReactionError(
"not-found",
`No existing address found with ID ${address._id}`
);
const types = [];
if (address.isBillingDefault) types.push("isBillingDefault");
if (address.isShippingDefault) types.push("isShippingDefault");
// If type is provided, set updated address to be default for `type`
if (type) Object.assign(address, { [type]: true });
// Update all other to set the default type to false
account.profile.addressBook.forEach((addr) => {
if (addr._id === address._id) Object.assign(addr, address);
else types.length && types.forEach((type) => { Object.assign(addr, { [type]: false }); });
if (addr._id === address._id) {
Object.assign(addr, address);
} else if (type) {
Object.assign(addr, { [type]: false });
}
});
const accountsUpdateQuery = { $set: { "profile.addressBook": account.profile.addressBook } };
// selector["profile.addressBook._id"] = address._id;
// const accountsUpdateQuery = { $set: { "profile.addressBook": account.profile.addressBook } };
const accountsUpdateQuery = {
$set: {
"profile.addressBook": account.profile.addressBook,
},
};
// Update the name when there is no name or the user updated his only shipping address
if ( !account.name || (account.profile && account.profile.addressbook && account.profile.addressbook.length <= 1))
if (
!account.name ||
(account.profile && account.profile.addressbook && account.profile.addressbook.length <= 1)
)
accountsUpdateQuery.$set.name = address.fullName;

@@ -65,3 +80,3 @@

const { value: updatedAccount } = await Accounts.findOneAndUpdate(
selector,
{ userId },
accountsUpdateQuery,

@@ -71,4 +86,5 @@ { returnOriginal: false }

if (!updatedAccount)
if (!updatedAccount) {
throw new ReactionError("server-error", "Unable to update account address");
}

@@ -79,3 +95,5 @@ // Create an array which contains all fields that have changed

Object.keys(address).forEach((key) => {
if (address[key] !== oldAddress[key]) updatedFields.push(key);
if (address[key] !== oldAddress[key]) {
updatedFields.push(key);
}
});

@@ -85,8 +103,8 @@

account: updatedAccount,
updatedBy: requestedAccountId,
updatedBy: userId,
updatedFields,
});
// If the address update was successful, then return the full updated address.
// Since we just pushed into `profile.addressBook`, we know it will exist.
// // If the address update was successful, then return the full updated address.
// // Since we just pushed into `profile.addressBook`, we know it will exist.
return updatedAccount.profile.addressBook.find(

@@ -93,0 +111,0 @@ (updatedAddress) => address._id === updatedAddress._id

@@ -8,3 +8,3 @@ import { decodeAccountOpaqueId } from "../../xforms/id.js";

* @summary resolver for the addAccountAddressBookEntry GraphQL mutation
* @param {Object} _ - unused
* @param {Object} parentResult - unused
* @param {Object} args.input - an object of all mutation arguments that were sent by the client

@@ -16,14 +16,9 @@ * @param {String} args.input.accountId - The account ID

*/
export default async function addAccountAddressBookEntry(_, { input }, context) {
const { address, accountId: opaqueAccountId, clientMutationId = null } = input;
const updatedAddress = await context.mutations.addAddressBook(context, {
accountId: opaqueAccountId && decodeAccountOpaqueId(opaqueAccountId),
address,
});
export default async function addAccountAddressBookEntry(parentResult, { input }, context) {
const { address, clientMutationId = null } = input;
const updatedAddress = await context.mutations.addAddressBook(context, { address });
return {
address: updatedAddress,
clientMutationId,
clientMutationId
};
}

@@ -18,3 +18,3 @@ import { decodeAccountOpaqueId, decodeAddressOpaqueId } from "../../xforms/id.js";

const { accountId, addressId, clientMutationId = null } = input;
const decodedAccountId = accountId && decodeAccountOpaqueId(accountId);
const decodedAccountId = decodeAccountOpaqueId(accountId);
const decodedAddressId = decodeAddressOpaqueId(addressId);

@@ -24,3 +24,3 @@

addressId: decodedAddressId,
accountId: decodedAccountId,
accountId: decodedAccountId
});

@@ -27,0 +27,0 @@

@@ -20,7 +20,6 @@ import { decodeAccountOpaqueId } from "../../xforms/id.js";

export default async function updateAccount(_, { input }, context) {
const { clientMutationId = null, accountId: opaqueAccountId, ...otherInput } = input;
const { clientMutationId = null, ...otherInput } = input;
const updatedAccount = await context.mutations.updateAccount(context, {
const updatedAccount = await context.mutations.updateAccount(context, {
...otherInput,
accountId: opaqueAccountId && decodeAccountOpaqueId(opaqueAccountId),
});

@@ -27,0 +26,0 @@

@@ -19,3 +19,3 @@ import { assocAddressInternalId, decodeAccountOpaqueId } from "../../xforms/id.js";

export default async function updateAccountAddressBookEntry(_, { input }, context) {
const { addressId, clientMutationId, updates, accountId: opaqueAccountId } = input;
const { addressId, clientMutationId, type, updates } = input;
const address = assocAddressInternalId({ ...updates, _id: addressId });

@@ -25,3 +25,3 @@

address,
accountId: opaqueAccountId && decodeAccountOpaqueId(opaqueAccountId),
type
});

@@ -28,0 +28,0 @@

@@ -447,2 +447,3 @@ import SimpleSchema from "simpl-schema";

defaultValue: "default",
optional: true,
},

@@ -452,2 +453,3 @@ site: {

defaultValue: "default",
optional: true,
},

@@ -461,2 +463,3 @@ type: {

defaultValue: "default",
optional: true,
},

@@ -466,2 +469,3 @@ state: {

defaultValue: "default",
optional: true,
},

@@ -471,2 +475,3 @@ phone: {

defaultValue: "default",
optional: true,
},

@@ -476,2 +481,3 @@ address: {

defaultValue: "default",
optional: true,
},

@@ -586,11 +592,11 @@ });

type: Boolean,
required: true,
optional: true,
},
personalDataToOtherCompanies: {
type: Boolean,
required: true,
optional: true,
},
personalDataToPromotionalOffers: {
type: Boolean,
required: true,
optional: true,
},

@@ -597,0 +603,0 @@ });

@@ -17,8 +17,13 @@ import _ from "lodash";

*/
export default async function sendVerificationEmail(context, { bodyTemplate = "accounts/verifyEmail", userId, url }) {
export default async function sendVerificationEmail(
context,
{ bodyTemplate = "accounts/verifyEmail", userId, url, target }
) {
const {
collections: { Accounts, Shops },
mutations: { startIdentityEmailVerification }
mutations: { startIdentityEmailVerification },
} = context;
let confirmationUrl = null;
if (typeof startIdentityEmailVerification !== "function") {

@@ -28,3 +33,5 @@ throw new ReactionError("not-supported", "Verification not supported");

const { email, token } = await startIdentityEmailVerification(context, { userId });
const { email, token } = await startIdentityEmailVerification(context, {
userId,
});

@@ -38,4 +45,15 @@ const account = await Accounts.findOne({ userId });

if (!shop) throw new ReactionError("not-found", "Shop not found");
const language = (account.profile && account.profile.language) || shop.language;
const confirmationUrl =`https://${url}/${language}/verify/${email}/${token}`;
const language =
(account.profile && account.profile.language) || shop.language;
console.log(url);
if (url.includes("admin.") || url.includes("localhost")) {
confirmationUrl = `https://${url}/verify/${email}/${token}`;
} else {
confirmationUrl = `https://${url}/${language}/verify/${email}/${token}`;
}
// TODO: This is a temporary solution to open link from email in the same tab
// We need to make it configurable in the future
target = "sellerRegistration";
const dataForEmail = {

@@ -48,13 +66,16 @@ // Reaction Information

physicalAddress: {
address: `${_.get(shop, "addressBook[0].address1")} ${_.get(shop, "addressBook[0].address2")}`,
address: `${_.get(shop, "addressBook[0].address1")} ${_.get(
shop,
"addressBook[0].address2"
)}`,
city: _.get(shop, "addressBook[0].city"),
region: _.get(shop, "addressBook[0].region"),
postal: _.get(shop, "addressBook[0].postal")
postal: _.get(shop, "addressBook[0].postal"),
},
shopName: shop.name,
confirmationUrl,
userEmailAddress: email
userEmailAddress: email,
target,
};
return context.mutations.sendEmail(context, {

@@ -65,4 +86,4 @@ data: dataForEmail,

language,
to: email
to: email,
});
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc