Skip to content

Commit 54a6ef9

Browse files
authored
chore: Move token from params to headers (#11281)
* chore: Move token from params to body * chore: Add type * wip * chore: clean up * clean ip
1 parent 4ec5219 commit 54a6ef9

File tree

7 files changed

+96
-75
lines changed

7 files changed

+96
-75
lines changed

integration-tests/http/__tests__/auth/admin/auth.spec.ts

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ medusaIntegrationTestRunner({
150150
.post("/auth/user/emailpass/reset-password", {})
151151
.catch((e) => e)
152152

153+
expect(errResponse.response.data.message).toEqual(
154+
"Invalid request: Field 'identifier' is required"
155+
)
153156
expect(errResponse.response.status).toEqual(400)
154157
})
155158

@@ -170,15 +173,6 @@ medusaIntegrationTestRunner({
170173
expect(response.status).toEqual(201)
171174
})
172175

173-
it("should fail to generate token for existing user but no provider, but still respond with 201", async () => {
174-
const response = await api.post(
175-
"/auth/user/non-existing-provider/reset-password",
176-
{ identifier: "admin@medusa.js" }
177-
)
178-
179-
expect(response.status).toEqual(201)
180-
})
181-
182176
it("should successfully reset password", async () => {
183177
// Register user
184178
await api.post("/auth/user/emailpass/register", {
@@ -199,10 +193,14 @@ medusaIntegrationTestRunner({
199193
})
200194

201195
const response = await api.post(
202-
`/auth/user/emailpass/update?token=${result}`,
196+
`/auth/user/emailpass/update`,
203197
{
204-
email: "test@medusa-commerce.com",
205198
password: "new_password",
199+
},
200+
{
201+
headers: {
202+
authorization: `Bearer ${result}`,
203+
},
206204
}
207205
)
208206

@@ -250,10 +248,15 @@ medusaIntegrationTestRunner({
250248
})
251249

252250
const response = await api.post(
253-
`/auth/user/emailpass/update?token=${result}`,
251+
`/auth/user/emailpass/update`,
254252
{
255253
email: "test+new@medusa-commerce.com",
256254
password: "new_password",
255+
},
256+
{
257+
headers: {
258+
authorization: `Bearer ${result}`,
259+
},
257260
}
258261
)
259262

@@ -306,10 +309,17 @@ medusaIntegrationTestRunner({
306309
jest.advanceTimersByTime(15 * 60 * 1000)
307310

308311
const response = await api
309-
.post(`/auth/user/emailpass/update?token=${result}`, {
310-
email: "test@medusa-commerce.com",
311-
password: "new_password",
312-
})
312+
.post(
313+
`/auth/user/emailpass/update`,
314+
{
315+
password: "new_password",
316+
},
317+
{
318+
headers: {
319+
authorization: `Bearer ${result}`,
320+
},
321+
}
322+
)
313323
.catch((e) => e)
314324

315325
expect(response.response.status).toEqual(401)
@@ -363,10 +373,17 @@ medusaIntegrationTestRunner({
363373
jest.advanceTimersByTime(15 * 60 * 1000)
364374

365375
const response = await api
366-
.post(`/auth/customer/emailpass/update?token=${result}`, {
367-
email: "test@medusa-commerce.com",
368-
password: "new_password",
369-
})
376+
.post(
377+
`/auth/customer/emailpass/update`,
378+
{
379+
password: "new_password",
380+
},
381+
{
382+
headers: {
383+
authorization: `Bearer ${result}`,
384+
},
385+
}
386+
)
370387
.catch((e) => e)
371388

372389
expect(response.response.status).toEqual(401)
@@ -398,10 +415,17 @@ medusaIntegrationTestRunner({
398415
jest.advanceTimersByTime(15 * 60 * 1000)
399416

400417
const response = await api
401-
.post(`/auth/user/emailpass/update?token=${result}`, {
402-
email: "test@medusa-commerce.com",
403-
password: "new_password",
404-
})
418+
.post(
419+
`/auth/user/emailpass/update`,
420+
{
421+
password: "new_password",
422+
},
423+
{
424+
headers: {
425+
authorization: `Bearer ${result}`,
426+
},
427+
}
428+
)
405429
.catch((e) => e)
406430

407431
expect(response.response.status).toEqual(401)

packages/admin/dashboard/src/hooks/api/auth.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const useLogout = (options?: UseMutationOptions<void, FetchError>) => {
6262

6363
export const useUpdateProviderForEmailPass = (
6464
token: string,
65-
options?: UseMutationOptions<void, FetchError, { password: string }>
65+
options?: UseMutationOptions<void, FetchError, HttpTypes.AdminUpdateProvider>
6666
) => {
6767
return useMutation({
6868
mutationFn: (payload) =>

packages/core/core-flows/src/auth/workflows/generate-reset-password-token.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ import { emitEventStep, useRemoteQueryStep } from "../../common"
1515
* [Generate Reset Password Token for Admin](https://docs.medusajs.com/api/admin#auth_postactor_typeauth_providerresetpassword)
1616
* and [Generate Reset Password Token for Customer](https://docs.medusajs.com/api/store#auth_postactor_typeauth_providerresetpassword)
1717
* API Routes.
18-
*
18+
*
1919
* The workflow emits the `auth.password_reset` event, which you can listen to in
2020
* a [subscriber](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers). Follow
2121
* [this guide](https://docs.medusajs.com/resources/commerce-modules/auth/reset-password) to learn
2222
* how to handle this event.
23-
*
23+
*
2424
* You can use this workflow within your customizations or your own custom workflows, allowing you to
2525
* generate reset password tokens within your custom flows.
26-
*
26+
*
2727
* @example
2828
* const { result } = await generateResetPasswordTokenWorkflow(container)
2929
* .run({
@@ -34,9 +34,9 @@ import { emitEventStep, useRemoteQueryStep } from "../../common"
3434
* secret: "jwt_123" // jwt secret
3535
* }
3636
* })
37-
*
37+
*
3838
* @summary
39-
*
39+
*
4040
* Generate a reset password token for a user or customer.
4141
*/
4242
export const generateResetPasswordTokenWorkflow = createWorkflow(
@@ -90,11 +90,6 @@ export const generateResetPasswordTokenWorkflow = createWorkflow(
9090
eventName: AuthWorkflowEvents.PASSWORD_RESET,
9191
data: {
9292
entity_id: input.entityId,
93-
/**
94-
* Use `actor_type` instead. Will be removed in a future version.
95-
* @deprecated
96-
*/
97-
actorType: input.actorType,
9893
actor_type: input.actorType,
9994
token,
10095
},

packages/core/framework/src/http/middlewares/authenticate-middleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ const getAuthContextFromSession = (
170170
return null
171171
}
172172

173-
const getAuthContextFromJwtToken = (
173+
export const getAuthContextFromJwtToken = (
174174
authHeader: string | undefined,
175175
jwtSecret: string,
176176
authTypes: AuthType[],

packages/core/js-sdk/src/auth/index.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class Auth {
2020
* @param payload - The data to pass in the request's body for authentication. When using the `emailpass` provider,
2121
* you pass the email and password.
2222
* @returns The JWT token used for registration later.
23-
*
23+
*
2424
* @tags auth
2525
*
2626
* @example
@@ -68,7 +68,7 @@ export class Auth {
6868
* @param payload - The data to pass in the request's body for authentication. When using the `emailpass` provider,
6969
* you pass the email and password.
7070
* @returns The authentication JWT token
71-
*
71+
*
7272
* @tags auth
7373
*
7474
* @example
@@ -116,7 +116,7 @@ export class Auth {
116116
* @param query - The query parameters from the Oauth callback, which should be passed to the API route. This includes query parameters like
117117
* `code` and `state`.
118118
* @returns The authentication JWT token
119-
*
119+
*
120120
* @tags auth
121121
*
122122
* @example
@@ -125,7 +125,7 @@ export class Auth {
125125
* "google",
126126
* {
127127
* code: "123",
128-
* state: "456"
128+
* state: "456"
129129
* }
130130
* ).then((token) => {
131131
* console.log(token)
@@ -158,7 +158,7 @@ export class Auth {
158158
* with {@link callback}. It sends a request to the [Refresh Authentication Token API route](https://docs.medusajs.com/api/admin#auth_postadminauthtokenrefresh).
159159
*
160160
* @returns The refreshed JWT authentication token.
161-
*
161+
*
162162
* @tags auth
163163
*
164164
* @example
@@ -184,7 +184,7 @@ export class Auth {
184184
/**
185185
* This method deletes the authentication session of the currently logged-in user to log them out.
186186
* It sends a request to the [Delete Authentication Session API route](https://docs.medusajs.com/api/admin#auth_deletesession).
187-
*
187+
*
188188
* @tags auth
189189
*
190190
* @example
@@ -214,7 +214,7 @@ export class Auth {
214214
* @param actor - The actor type. For example, `user` for admin user, or `customer` for customer.
215215
* @param provider - The authentication provider to use. For example, `emailpass`.
216216
* @param body - The data required to identify the user.
217-
*
217+
*
218218
* @tags auth
219219
*
220220
* @example
@@ -261,7 +261,7 @@ export class Auth {
261261
* @param provider - The authentication provider to use. For example, `emailpass`.
262262
* @param body - The data necessary to update the user's authentication data. When resetting the user's password,
263263
* send the `password` property.
264-
*
264+
*
265265
* @tags auth
266266
*
267267
* @example
@@ -280,16 +280,14 @@ export class Auth {
280280
updateProvider = async (
281281
actor: string,
282282
provider: string,
283-
body: Record<string, unknown>,
283+
body: HttpTypes.AdminUpdateProvider,
284284
token: string
285285
) => {
286-
await this.client.fetch(
287-
`/auth/${actor}/${provider}/update?token=${token}`,
288-
{
289-
method: "POST",
290-
body,
291-
}
292-
)
286+
await this.client.fetch(`/auth/${actor}/${provider}/update`, {
287+
method: "POST",
288+
body,
289+
headers: { Authorization: `Bearer ${token}` },
290+
})
293291
}
294292

295293
/**

packages/core/types/src/http/auth/payloads.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ export interface AdminSignUpWithEmailPassword {
55

66
export interface AdminSignInWithEmailPassword
77
extends AdminSignUpWithEmailPassword {}
8+
9+
export interface AdminUpdateProvider {
10+
[key: string]: unknown // Allow for any additional fields, this will vary depending on the provider
11+
}

packages/medusa/src/api/auth/utils/validate-token.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
AuthenticatedMedusaRequest,
3+
getAuthContextFromJwtToken,
34
MedusaNextFunction,
45
MedusaRequest,
56
MedusaResponse,
@@ -10,20 +11,37 @@ import {
1011
MedusaError,
1112
Modules,
1213
} from "@medusajs/framework/utils"
13-
import { decode, JwtPayload, verify } from "jsonwebtoken"
14+
import { HttpTypes } from "@medusajs/types"
15+
16+
export interface UpdateProviderJwtPayload {
17+
entity_id: string
18+
actor_type: string
19+
provider: string
20+
}
1421

1522
// Middleware to validate that a token is valid
1623
export const validateToken = () => {
1724
return async (
18-
req: MedusaRequest,
25+
req: MedusaRequest<HttpTypes.AdminUpdateProvider>,
1926
res: MedusaResponse,
2027
next: MedusaNextFunction
2128
) => {
2229
const { actor_type, auth_provider } = req.params
23-
const { token } = req.query
2430

2531
const req_ = req as AuthenticatedMedusaRequest
2632

33+
// @ts-ignore
34+
const { http } = req_.scope.resolve<ConfigModule>(
35+
ContainerRegistrationKeys.CONFIG_MODULE
36+
).projectConfig
37+
38+
const token = getAuthContextFromJwtToken(
39+
req.headers.authorization,
40+
http.jwtSecret as string,
41+
["bearer"],
42+
[actor_type]
43+
) as UpdateProviderJwtPayload | null
44+
2745
const errorObject = new MedusaError(
2846
MedusaError.Types.UNAUTHORIZED,
2947
`Invalid token`
@@ -33,27 +51,15 @@ export const validateToken = () => {
3351
return next(errorObject)
3452
}
3553

36-
// @ts-ignore
37-
const { http } = req_.scope.resolve<ConfigModule>(
38-
ContainerRegistrationKeys.CONFIG_MODULE
39-
).projectConfig
40-
4154
const authModule = req.scope.resolve<IAuthModuleService>(Modules.AUTH)
4255

43-
const decoded = decode(token as string) as JwtPayload
44-
45-
if (!decoded?.entity_id) {
46-
return next(errorObject)
47-
}
48-
49-
// E.g. token was requested for a customer, but attempted used for a user
50-
if (decoded?.actor_type !== actor_type) {
56+
if (!token?.entity_id) {
5157
return next(errorObject)
5258
}
5359

5460
const [providerIdentity] = await authModule.listProviderIdentities(
5561
{
56-
entity_id: decoded.entity_id,
62+
entity_id: token.entity_id,
5763
provider: auth_provider,
5864
},
5965
{
@@ -65,12 +71,6 @@ export const validateToken = () => {
6571
return next(errorObject)
6672
}
6773

68-
try {
69-
verify(token as string, http.jwtSecret as string) as JwtPayload
70-
} catch (error) {
71-
return next(errorObject)
72-
}
73-
7474
req_.auth_context = {
7575
actor_type,
7676
auth_identity_id: providerIdentity.auth_identity_id!,

0 commit comments

Comments
 (0)