Revamp the authentication setup (#7419)

* feat: Add email pass authentication provider package

* feat: Revamp auth module and remove concept of scope

* feat: Revamp the auth module to be more standardized in how providers are loaded

* feat: Switch from scope to actor type for authentication

* feat: Add support for per-actor auth methods

* feat: Add emailpass auth provider by default

* fix: Add back app_metadata in auth module
This commit is contained in:
Stevche Radevski
2024-05-23 20:56:40 +02:00
committed by GitHub
parent 7b0cfe3b77
commit 8a070d5d85
100 changed files with 991 additions and 1005 deletions
@@ -0,0 +1,138 @@
import { MedusaError } from "@medusajs/utils"
import Scrypt from "scrypt-kdf"
import { EmailPassAuthService } from "../../src/services/emailpass"
jest.setTimeout(100000)
describe("Email password auth provider", () => {
let emailpassService: EmailPassAuthService
beforeAll(() => {
emailpassService = new EmailPassAuthService(
{
logger: console as any,
},
{}
)
})
afterEach(() => {
jest.restoreAllMocks()
})
it("return error if email is not passed", async () => {
const resp = await emailpassService.authenticate(
{ body: { password: "otherpass" } },
{}
)
expect(resp).toEqual({
error: "Email should be a string",
success: false,
})
})
it("return error if password is not passed", async () => {
const resp = await emailpassService.authenticate(
{ body: { email: "test@admin.com" } },
{}
)
expect(resp).toEqual({
error: "Password should be a string",
success: false,
})
})
it("return error if the passwords don't match", async () => {
const config = { logN: 15, r: 8, p: 1 }
const passwordHash = await Scrypt.kdf("somepass", config)
const authServiceSpies = {
retrieve: jest.fn().mockImplementation(() => {
return {
entity_id: "test@admin.com",
provider: "emailpass",
provider_metadata: {
password: passwordHash.toString("base64"),
},
}
}),
}
const resp = await emailpassService.authenticate(
{ body: { email: "test@admin.com", password: "otherpass" } },
authServiceSpies
)
expect(authServiceSpies.retrieve).toHaveBeenCalled()
expect(resp).toEqual({
error: "Invalid email or password",
success: false,
})
})
it("return an existing entity if the passwords match", async () => {
const config = { logN: 15, r: 8, p: 1 }
const passwordHash = await Scrypt.kdf("somepass", config)
const authServiceSpies = {
retrieve: jest.fn().mockImplementation(() => {
return {
entity_id: "test@admin.com",
provider: "emailpass",
provider_metadata: {
password: passwordHash.toString("base64"),
},
}
}),
}
const resp = await emailpassService.authenticate(
{ body: { email: "test@admin.com", password: "somepass" } },
authServiceSpies
)
expect(authServiceSpies.retrieve).toHaveBeenCalled()
expect(resp).toEqual(
expect.objectContaining({
success: true,
authIdentity: expect.objectContaining({
entity_id: "test@admin.com",
provider_metadata: {},
}),
})
)
})
it("creates a new auth identity if it doesn't exist", async () => {
const authServiceSpies = {
retrieve: jest.fn().mockImplementation(() => {
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Not found")
}),
create: jest.fn().mockImplementation(() => {
return {
entity_id: "test@admin.com",
provider: "emailpass",
provider_metadata: {
password: "somehash",
},
}
}),
}
const resp = await emailpassService.authenticate(
{ body: { email: "test@admin.com", password: "test" } },
authServiceSpies
)
expect(authServiceSpies.retrieve).toHaveBeenCalled()
expect(authServiceSpies.create).toHaveBeenCalled()
expect(resp.authIdentity).toEqual(
expect.objectContaining({
entity_id: "test@admin.com",
provider_metadata: {},
})
)
})
})