feat(medusa): Authentication overhaul (#4064)
* implemented bearer auth * changed naming strat * changed session auth to not use jwt * typo * changed auth header prefix for admin api token auth * fixed supporting functions to work with new session type * removed database calls for bearer auth improving performance * removed unused deps * changed auth in tests * added integration tests * Accepted suggested change Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> * Typo Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * more typos Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * proper formatting Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * removed endregion Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * removed startregion Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * fixed admin JWT integration test * added more fixes to integration tests * Update OAS * Create fluffy-donkeys-hope.md * created API reference for new auth * implemented getToken in medusa-js * Apply suggestions from code review Co-authored-by: Shahed Nasser <shahednasser@gmail.com> * Apply suggestions from code review Co-authored-by: Shahed Nasser <shahednasser@gmail.com> * deleted files which should be autogenerated * Update fluffy-donkeys-hope.md * JSDoc update Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> * added missing route exports * implemented runtime domain safety in jwt token manager * fixed jwt manager * lint get-token files * Update fluffy-donkeys-hope.md * Revert "deleted files which should be autogenerated" This reverts commit cd5e86623b822e6a6ac37322b952143ccc493df9. * Revert "Apply suggestions from code review" This reverts commit f02f07ce58fd9fcc2dfc80cadbb9df2665108d65. * Revert "created API reference for new auth" This reverts commit c9eafbb36453f5cf8047c79e94f470cb2d023c7d. * renamed header for sending api access tokens * medusa-js - changed apiKey header --------- Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Co-authored-by: olivermrbl <oliver@mrbltech.com> Co-authored-by: Shahed Nasser <shahednasser@gmail.com>
This commit is contained in:
co-authored by
Carlos R. L. Rodrigues
Oliver Windall Juhl
Shahed Nasser
olivermrbl
parent
07e65f5aba
commit
2caff2efc7
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* `JwtTokenManager` holds JWT tokens in state.
|
||||
*/
|
||||
class JwtTokenManager {
|
||||
private adminJwt: string | null = null;
|
||||
private storeJwt: string | null = null;
|
||||
|
||||
/**
|
||||
* Set a store or admin jwt token to be sent with each request.
|
||||
*/
|
||||
public registerJwt(token: string, domain: "admin" | "store") {
|
||||
if (domain === "admin") {
|
||||
this.adminJwt = token;
|
||||
} else if (domain === "store") {
|
||||
this.storeJwt = token;
|
||||
} else {
|
||||
throw new Error(`'domain' must be wither 'admin' or 'store' received ${domain}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the store or admin jwt token
|
||||
*/
|
||||
public getJwt(domain: "admin" | "store") {
|
||||
if (domain === "admin") {
|
||||
return this.adminJwt;
|
||||
} else if (domain === "store") {
|
||||
return this.storeJwt;
|
||||
} else {
|
||||
throw new Error(`'domain' must be wither 'admin' or 'store' received ${domain}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export singleton instance.
|
||||
*/
|
||||
export default new JwtTokenManager()
|
||||
@@ -3,6 +3,7 @@ import * as rax from "retry-axios"
|
||||
import { v4 as uuidv4 } from "uuid"
|
||||
|
||||
import KeyManager from "./key-manager"
|
||||
import JwtTokenManager from "./jwt-token-manager"
|
||||
|
||||
const unAuthenticatedAdminEndpoints = {
|
||||
"/admin/auth": "POST",
|
||||
@@ -125,7 +126,16 @@ class Client {
|
||||
if (this.config.apiKey && this.requiresAuthentication(path, method)) {
|
||||
defaultHeaders = {
|
||||
...defaultHeaders,
|
||||
Authorization: `Bearer ${this.config.apiKey}`,
|
||||
"x-medusa-access-token": this.config.apiKey,
|
||||
}
|
||||
}
|
||||
|
||||
const domain: "admin" | "store" = path.includes("admin") ? "admin" : "store"
|
||||
|
||||
if (JwtTokenManager.getJwt(domain)) {
|
||||
defaultHeaders = {
|
||||
...defaultHeaders,
|
||||
Authorization: `Bearer ${JwtTokenManager.getJwt(domain)}`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AdminAuthRes, AdminPostAuthReq } from "@medusajs/medusa"
|
||||
import { AdminAuthRes, AdminPostAuthReq, AdminBearerAuthRes } from "@medusajs/medusa"
|
||||
import { ResponsePromise } from "../../typings"
|
||||
import JwtTokenManager from "../../jwt-token-manager"
|
||||
import BaseResource from "../base"
|
||||
|
||||
class AdminAuthResource extends BaseResource {
|
||||
@@ -41,6 +42,25 @@ class AdminAuthResource extends BaseResource {
|
||||
const path = `/admin/auth`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieves a new JWT access token
|
||||
* @param {AdminPostAuthReq} payload
|
||||
* @param customHeaders
|
||||
* @return {ResponsePromise<AdminBearerAuthRes>}
|
||||
*/
|
||||
getToken(
|
||||
payload: AdminPostAuthReq,
|
||||
customHeaders: Record<string, any> = {}
|
||||
): ResponsePromise<AdminBearerAuthRes> {
|
||||
const path = `/admin/auth/token`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
.then((res) => {
|
||||
JwtTokenManager.registerJwt(res.access_token, "admin");
|
||||
|
||||
return res
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminAuthResource
|
||||
|
||||
@@ -2,8 +2,10 @@ import {
|
||||
StoreGetAuthEmailRes,
|
||||
StorePostAuthReq,
|
||||
StoreAuthRes,
|
||||
StoreBearerAuthRes,
|
||||
} from "@medusajs/medusa"
|
||||
import { ResponsePromise } from "../typings"
|
||||
import JwtTokenManager from "../jwt-token-manager"
|
||||
import BaseResource from "./base"
|
||||
|
||||
class AuthResource extends BaseResource {
|
||||
@@ -48,6 +50,25 @@ class AuthResource extends BaseResource {
|
||||
const path = `/store/auth/${email}`
|
||||
return this.client.request("GET", path, undefined, {}, customHeaders)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieves a new JWT access token
|
||||
* @param {AdminPostAuthReq} payload
|
||||
* @param customHeaders
|
||||
* @return {ResponsePromise<AdminBearerAuthRes>}
|
||||
*/
|
||||
getToken(
|
||||
payload: StorePostAuthReq,
|
||||
customHeaders: Record<string, any> = {}
|
||||
): ResponsePromise<StoreBearerAuthRes> {
|
||||
const path = `/store/auth/token`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
.then((res) => {
|
||||
JwtTokenManager.registerJwt(res.data.access_token, "store");
|
||||
|
||||
return res
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthResource
|
||||
|
||||
Reference in New Issue
Block a user