Cannot include logged-in user token when fetching product list
ddombrowsky opened this issue ยท 9 comments
Context
There appears to be no way to pass an auth token along with a call to list products. Because of this, the back end cannot determine which user is requesting the product list, preventing me from implementing members-only pricing or products.
e.g. this code
const response = await spreeClient.products.list({
include: "images",
bearerToken: token ? token.access : undefined
});
will not pass through the bearerToken
.
Expected Behavior
The request should include the Authorize:
header field, as it does with the cart operations.
Possible Fix
The API call should be updated to include the optional parameter.
Your Environment
- Library version: 4.4.3
- Node and yarn/npm version: node 14.15.4, npm 7.20.3
Some variant of this, perhaps? This changes the API though. Not sure if there's a way around that.
diff --git a/src/endpoints/Products.ts b/src/endpoints/Products.ts
index ca836e5..399ff06 100644
--- a/src/endpoints/Products.ts
+++ b/src/endpoints/Products.ts
@@ -1,14 +1,15 @@
import Http from '../Http'
import { IProductResult, IProductsResult } from '../interfaces/Product'
import { IQuery } from '../interfaces/Query'
+import { IToken } from '../interfaces/Token'
import routes from '../routes'
export default class Products extends Http {
- public async list(params: IQuery = {}): Promise<IProductsResult> {
- return (await this.spreeResponse('get', routes.productsPath(), {}, params)) as IProductsResult
+ public async list(token: IToken, params: IQuery = {}): Promise<IProductsResult> {
+ return (await this.spreeResponse('get', routes.productsPath(), token, params)) as IProductsResult
}
- public async show(id: string, params: IQuery = {}): Promise<IProductResult> {
- return (await this.spreeResponse('get', routes.productPath(id), {}, params)) as IProductResult
+ public async show(token: IToken, id: string, params: IQuery = {}): Promise<IProductResult> {
+ return (await this.spreeResponse('get', routes.productPath(id), token, params)) as IProductResult
}
}
diff --git a/types/endpoints/Products.d.ts b/types/endpoints/Products.d.ts
index 2481dd1..1c600b2 100644
--- a/types/endpoints/Products.d.ts
+++ b/types/endpoints/Products.d.ts
@@ -1,7 +1,8 @@
import Http from '../Http';
import { IProductResult, IProductsResult } from '../interfaces/Product';
import { IQuery } from '../interfaces/Query';
+import { IToken } from '../interfaces/Token';
export default class Products extends Http {
- list(params?: IQuery): Promise<IProductsResult>;
- show(id: string, params?: IQuery): Promise<IProductResult>;
+ list(token: IToken, params?: IQuery): Promise<IProductsResult>;
+ show(token: IToken, id: string, params?: IQuery): Promise<IProductResult>;
}
The call would end up being
const response = await spreeClient.products.list({
bearerToken: token ? token.access_token : undefined
}, {
include: "images",
});
applied the above patch to the fork here: https://github.com/ddombrowsky/spree-storefront-api-v2-js-sdk/tree/instinct-dna
Hey @ddombrowsky could you create a PR with these changes to this repo? :)
@damianlegawiec ๐ Do you think an optional token should be added to the stock Spree SDK? Is it a common need to send a bearer token with list and show requests? These endpoints can be extended inside the project instead. For example:
class ExtendedProducts extends endpoints.Products {
public list(params: IQuery = {}, token?: IToken): Promise<IProductsResult> {
return this.spreeResponse('get', routes.productsPath(), token, params)
}
public show(id: string, params: IQuery = {}, token?: IToken): Promise<IProductResult> {
return this.spreeResponse('get', routes.productPath(id), token, params)
}
}
If we're going to allow sending a token with product requests, we must make it optional.
@damianlegawiec ๐ Do you think an optional token should be added to the stock Spree SDK? Is it a common need to send a bearer token with list and show requests? These endpoints can be extended inside the project instead. For example:
class ExtendedProducts extends endpoints.Products { public list(params: IQuery = {}, token?: IToken): Promise<IProductsResult> { return this.spreeResponse('get', routes.productsPath(), token, params) } public show(id: string, params: IQuery = {}, token?: IToken): Promise<IProductResult> { return this.spreeResponse('get', routes.productPath(id), token, params) } }If we're going to allow sending a token with product requests, we must make it optional.
We need to add an option to send that token for all endpoints.
Hey @ddombrowsky could you create a PR with these changes to this repo? :)
PR created: #225
Thanks for the PR.
We'll have to update the README too.