|
|
@@ -0,0 +1,71 @@
|
|
|
+import ms from 'ms';
|
|
|
+
|
|
|
+import { RequestContext } from '../../api/common/request-context';
|
|
|
+import { InjectableStrategy } from '../../common/types/injectable-strategy';
|
|
|
+import { Order } from '../../entity/order/order.entity';
|
|
|
+
|
|
|
+/**
|
|
|
+ * @description
|
|
|
+ * The OrderByCodeAccessStrategy determines how access to a placed Order via the
|
|
|
+ * orderByCode query is granted.
|
|
|
+ * With a custom strategy anonymous access could be made permanent or tied to specific
|
|
|
+ * conditions like IP range or an Order status.
|
|
|
+ *
|
|
|
+ * @example
|
|
|
+ * This example grants access to the requested Order to anyone – unless it's Monday.
|
|
|
+ * ```TypeScript
|
|
|
+ * export class NotMondayOrderByCodeAccessStrategy implements OrderByCodeAccessStrategy {
|
|
|
+ * canAccessOrder(ctx: RequestContext, order: Order): boolean {
|
|
|
+ * const MONDAY = 1;
|
|
|
+ * const today = (new Date()).getDay();
|
|
|
+ *
|
|
|
+ * return today !== MONDAY;
|
|
|
+ * }
|
|
|
+ * }
|
|
|
+ * ```
|
|
|
+ *
|
|
|
+ * @docsCategory orders
|
|
|
+ * @docsPage OrderByCodeAccessStrategy
|
|
|
+ */
|
|
|
+export interface OrderByCodeAccessStrategy extends InjectableStrategy {
|
|
|
+ /**
|
|
|
+ * @description
|
|
|
+ * Gives or denies permission to access the requested Order
|
|
|
+ */
|
|
|
+ canAccessOrder(ctx: RequestContext, order: Order): boolean | Promise<boolean>;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @description
|
|
|
+ * The default OrderByCodeAccessStrategy used by Vendure. It permitts permanent access to
|
|
|
+ * the Customer owning the Order and anyone within a given time period after placing the Order
|
|
|
+ * (defaults to 2h).
|
|
|
+ *
|
|
|
+ * @param anonymousAccessDuration value for [ms](https://github.com/vercel/ms), e.g. `2h` for 2 hours or `5d` for 5 days
|
|
|
+ *
|
|
|
+ * @docsCategory orders
|
|
|
+ * @docsPage OrderByCodeAccessStrategy
|
|
|
+ */
|
|
|
+export class DefaultOrderByCodeAccessStrategy implements OrderByCodeAccessStrategy {
|
|
|
+ private anonymousAccessDuration;
|
|
|
+
|
|
|
+ constructor(anonymousAccessDuration: string) {
|
|
|
+ this.anonymousAccessDuration = anonymousAccessDuration;
|
|
|
+ }
|
|
|
+
|
|
|
+ canAccessOrder(ctx: RequestContext, order: Order): boolean {
|
|
|
+ // Order owned by active user
|
|
|
+ const activeUserMatches = order?.customer?.user?.id === ctx.activeUserId;
|
|
|
+
|
|
|
+ // For guest Customers, allow access to the Order for the following
|
|
|
+ // time period
|
|
|
+ const anonymousAccessPermitted = () => {
|
|
|
+ const anonymousAccessLimit = ms(this.anonymousAccessDuration);
|
|
|
+ const orderPlaced = order.orderPlacedAt ? +order.orderPlacedAt : 0;
|
|
|
+ const now = Date.now();
|
|
|
+ return now - orderPlaced < anonymousAccessLimit;
|
|
|
+ };
|
|
|
+
|
|
|
+ return (ctx.activeUserId && activeUserMatches) || (!ctx.activeUserId && anonymousAccessPermitted());
|
|
|
+ }
|
|
|
+}
|