Skip to content

Commit

Permalink
add nonce
Browse files Browse the repository at this point in the history
  • Loading branch information
Xziy committed May 5, 2024
1 parent 2492b44 commit 2016b53
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 11 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export * from './models/UserDevice';
export * from './models/UserLocation';
export * from './models/UserOrderHistory';
export * from './models/Promotion';
export * from './libs/helpers/OrderHelper';
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ __exportStar(require("./models/UserDevice"), exports);
__exportStar(require("./models/UserLocation"), exports);
__exportStar(require("./models/UserOrderHistory"), exports);
__exportStar(require("./models/Promotion"), exports);
// Helpers
__exportStar(require("./libs/helpers/OrderHelper"), exports);
module.exports = function (sails) {
return {
defaults: require('./hook/defaults'),
Expand Down
3 changes: 3 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export * from './models/UserLocation';
export * from './models/UserOrderHistory';
export * from './models/Promotion';

// Helpers
export * from './libs/helpers/OrderHelper'

module.exports = function (sails) {
return {
defaults: require('./hook/defaults'),
Expand Down
2 changes: 2 additions & 0 deletions libs/AwaitEmitter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import OrderDish from "../models/OrderDish";
import Maintenance from "../models/Maintenance";
import { DialogBox } from "./DialogBox";
import Promotion from "../models/Promotion";
import { InitCheckout } from "./helpers/OrderHelper";
/**
* Naming conventions can greatly enhance the readability and understanding of code, especially for those who may not be familiar with it. Using a structured approach like "module:action-before/after-read/write" can make it intuitive. Let's break down the example "core:add-dish-before-write":
Expand Down Expand Up @@ -56,6 +57,7 @@ declare global {
"core:order-return-full-order-destroy-orderdish": [Dish, Order];
"core:order-before-count": [Order];
"core:order-payment": [Order, PaymentBack];
"core:order-init-checkout": [Order, InitCheckout];
"core:maintenance-enabled": [Maintenance];
"core:maintenance-disabled": [];
"core:group-get-menu": [Group[], string];
Expand Down
4 changes: 3 additions & 1 deletion libs/AwaitEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import OrderDish from "../models/OrderDish"
import Maintenance from "../models/Maintenance"
import { DialogBox } from "./DialogBox";
import Promotion from "../models/Promotion";
import { InitCheckout } from "./helpers/OrderHelper";

/**
* Naming conventions can greatly enhance the readability and understanding of code, especially for those who may not be familiar with it. Using a structured approach like "module:action-before/after-read/write" can make it intuitive. Let's break down the example "core:add-dish-before-write":
Expand Down Expand Up @@ -58,6 +59,7 @@ declare global {
"core:order-return-full-order-destroy-orderdish": [Dish, Order]
"core:order-before-count": [Order]
"core:order-payment": [Order, PaymentBack]
"core:order-init-checkout": [Order, InitCheckout]
"core:maintenance-enabled": [Maintenance]
"core:maintenance-disabled": []
"core:group-get-menu": [Group[], string]
Expand All @@ -73,7 +75,7 @@ declare global {
"dialog-box:new": [DialogBox]
"dialog-box:answer-received": [string, string]
"core:add-product-before-write": [Order, Dish]
"promotion-process:debug": [number, Order, Promotion, any]
"promotion-process:debug": [number, Order, Promotion, any],
}
}

Expand Down
22 changes: 22 additions & 0 deletions libs/helpers/OrderHelper.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Order from "../../models/Order";
export type InitCheckout = {
/** Order nonce */
nonce: number;
/**
* Intervals during which an order can be placed
* */
worktimeIntervals: [number, number][];
/**
* Will it be possible to order as quickly as possible?
*/
allowSoonAsPossible: boolean;
/**
* Allow order by time
*/
allowOrderToTime: boolean;
};
export declare class OrderHelper {
private constructor();
static initCheckout(populatedOrder: Order): Promise<InitCheckout>;
static orderHash(populatedOrder: Order): string;
}
37 changes: 37 additions & 0 deletions libs/helpers/OrderHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrderHelper = void 0;
const hashCode_1 = __importDefault(require("../hashCode"));
const stringsInArray_1 = require("../stringsInArray");
class OrderHelper {
constructor(orderId) {
}
static async initCheckout(populatedOrder) {
let initCheckout = {
worktimeIntervals: [],
allowSoonAsPossible: false,
allowOrderToTime: false,
nonce: 0
};
await emitter.emit('core:order-init-checkout', populatedOrder, initCheckout);
initCheckout.nonce = populatedOrder.nonce;
return initCheckout;
}
static orderHash(populatedOrder) {
const fieldsToExclude = [
'createdAt',
'updatedAt',
'shortId',
'isPromoting',
'nonce',
'hash'
];
let summarizeOrder = (0, stringsInArray_1.extractFieldValues)(populatedOrder, fieldsToExclude).join("");
let hash = (0, hashCode_1.default)(summarizeOrder);
return hash;
}
}
exports.OrderHelper = OrderHelper;
56 changes: 56 additions & 0 deletions libs/helpers/OrderHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Order from "../../models/Order";
import hashCode from "../hashCode";
import { extractFieldValues } from "../stringsInArray";

export type InitCheckout = {
/** Order nonce */
nonce: number
/**
* Intervals during which an order can be placed
* */
worktimeIntervals: [number, number][]

/**
* Will it be possible to order as quickly as possible?
*/
allowSoonAsPossible: boolean

/**
* Allow order by time
*/
allowOrderToTime: boolean
}
export class OrderHelper {
private constructor(orderId: string) {

}

public static async initCheckout(populatedOrder: Order): Promise<InitCheckout> {
let initCheckout: InitCheckout = {
worktimeIntervals: [],
allowSoonAsPossible: false,
allowOrderToTime: false,
nonce: 0
}
await emitter.emit('core:order-init-checkout', populatedOrder, initCheckout);
initCheckout.nonce = populatedOrder.nonce
return initCheckout;
}

public static orderHash(populatedOrder: Order): string {
const fieldsToExclude = [
'createdAt',
'updatedAt',
'shortId',
'isPromoting',
'nonce',
'hash'
]

let summarizeOrder = extractFieldValues(populatedOrder,fieldsToExclude).join("")

let hash: string = hashCode(summarizeOrder);

return hash
}
}
1 change: 1 addition & 0 deletions libs/stringsInArray.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export declare function stringsInArray(check: string[] | string, array: string[]): boolean;
export declare function someInArray(check: string[] | string, array: string[]): boolean;
export declare function extractFieldValues(obj: any, fields: any, exclude?: boolean, result?: any[]): any[];
21 changes: 20 additions & 1 deletion libs/stringsInArray.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.someInArray = exports.stringsInArray = void 0;
exports.extractFieldValues = exports.someInArray = exports.stringsInArray = void 0;
function stringsInArray(check, array) {
// If check is an array of strings
if (Array.isArray(check)) {
Expand Down Expand Up @@ -28,3 +28,22 @@ function someInArray(check, array) {
return array.some((e) => check.includes(e));
}
exports.someInArray = someInArray;
function extractFieldValues(obj, fields, exclude = true, result = []) {
if (typeof obj === 'object' && obj !== null) {
for (let key in obj) {
if (typeof obj[key] === 'object') {
extractFieldValues(obj[key], fields, exclude, result);
}
else if (fields.includes(key) !== exclude) {
if (Array.isArray(obj[key])) {
result.push(JSON.stringify(obj[key]));
}
else {
result.push(obj[key]);
}
}
}
}
return result;
}
exports.extractFieldValues = extractFieldValues;
20 changes: 19 additions & 1 deletion libs/stringsInArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,22 @@ export function someInArray(check: string[] | string, array: string[]) {
}

return array.some((e)=> check.includes(e));
}
}

export function extractFieldValues(obj, fields, exclude = true, result = []) {
if (typeof obj === 'object' && obj !== null) {
for (let key in obj) {
if (typeof obj[key] === 'object') {
extractFieldValues(obj[key], fields, exclude, result);
} else if (fields.includes(key) !== exclude) {
if (Array.isArray(obj[key])) {
result.push(JSON.stringify(obj[key]));
} else {
result.push(obj[key]);
}
}
}
}
return result;
}

10 changes: 10 additions & 0 deletions models/Order.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ declare let attributes: {
discountTotal: number;
orderDate: string;
deviceId: string;
/**
* A number that will change every time the order is changed
*/
nonce: number;
/**
* Populated order stringify hash
*/
hash: string;
/**
* Add IP, UserAgent for anonymous cart
*/
Expand Down Expand Up @@ -271,6 +279,8 @@ declare let Model: {
discountTotal?: number;
orderDate?: string;
deviceId?: string;
nonce?: number;
hash?: string;
user?: string | User;
customData?: any;
}>;
Expand Down
23 changes: 22 additions & 1 deletion models/Order.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("uuid");
const decimal_js_1 = __importDefault(require("decimal.js"));
const phoneValidByMask_1 = require("../libs/phoneValidByMask");
const OrderHelper_1 = require("../libs/helpers/OrderHelper");
let attributes = {
/** Id */
id: {
Expand Down Expand Up @@ -122,7 +123,7 @@ let attributes = {
/** */
dishesCount: "number",
uniqueDishes: "number",
modifiers: "json",
modifiers: "json", //TODO? for what?
customer: "json",
address: "json",
comment: "string",
Expand Down Expand Up @@ -231,6 +232,17 @@ let attributes = {
orderDate: "string",
// orderDateLimit: "string",
deviceId: "string",
/**
* A number that will change every time the order is changed
*/
nonce: {
type: "number",
defaultsTo: 0,
},
/**
* Populated order stringify hash
*/
hash: "string",
/**
* Add IP, UserAgent for anonymous cart
*/
Expand Down Expand Up @@ -996,6 +1008,15 @@ let Model = {
catch (e) {
sails.log.error("CART > fullOrder error", e);
}
const hash = OrderHelper_1.OrderHelper.orderHash(fullOrder);
// TODO: test "nonce should be update after countcart change"
let nonce = 0;
if (fullOrder.hash !== hash) {
if (typeof fullOrder.nonce === 'number' && isFinite(fullOrder.nonce)) {
nonce = fullOrder.nonce + 1;
}
await Order.update({ id: fullOrder.id }, { hash: hash, nonce: nonce });
}
return { ...fullOrder };
},
/**
Expand Down
Loading

0 comments on commit 2016b53

Please sign in to comment.