Feat(authentication): username password provider (#6052)

This commit is contained in:
Philip Korsholm
2024-01-23 09:04:22 +00:00
committed by GitHub
parent 9d7ed9dbaf
commit 24bb26b81a
20 changed files with 424 additions and 44 deletions
@@ -6,13 +6,16 @@ export async function createAuthUsers(
userData: any[] = [
{
id: "test-id",
entity_id: "test-id",
provider: "manual",
},
{
id: "test-id-1",
entity_id: "test-id-1",
provider: "manual",
},
{
entity_id: "test-id-2",
provider: "store",
},
]
@@ -229,6 +229,7 @@ describe("AuthUser Service", () => {
{
id: "test",
provider_id: "manual",
entity_id: "test"
},
])
@@ -237,6 +237,7 @@ describe("AuthenticationModuleService - AuthUser", () => {
{
id: "test",
provider_id: "manual",
entity_id: "test"
},
])
@@ -5,6 +5,7 @@ import { initialize } from "../../../../src"
import { DB_URL } from "@medusajs/pricing/integration-tests/utils"
import { MedusaModule } from "@medusajs/modules-sdk"
import { IAuthenticationModuleService } from "@medusajs/types"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
jest.setTimeout(30000)
@@ -22,6 +23,10 @@ describe("AuthenticationModuleService - AuthProvider", () => {
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
if(service.__hooks?.onApplicationStart) {
await service.__hooks.onApplicationStart()
}
})
afterEach(async () => {
@@ -30,7 +35,7 @@ describe("AuthenticationModuleService - AuthProvider", () => {
})
describe("listAuthProviders", () => {
it("should list default AuthProviders", async () => {
it("should list default AuthProviders registered by loaders", async () => {
const authProviders = await service.listAuthProviders()
const serialized = JSON.parse(JSON.stringify(authProviders))
@@ -42,4 +47,22 @@ describe("AuthenticationModuleService - AuthProvider", () => {
])
})
})
describe("authenticate", () => {
it("authenticate validates that a provider is registered in container", async () => {
await createAuthProviders(testManager, [
{
provider: "notRegistered",
name: "test",
},
])
const { success, error } = await service.authenticate("notRegistered", {})
expect(success).toBe(false)
expect(error).toEqual(
"AuthenticationProvider with for provider: notRegistered wasn't registered in the module. Have you configured your options correctly?"
)
})
})
})
@@ -0,0 +1,140 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import Scrypt from "scrypt-kdf"
import { MikroOrmWrapper } from "../../../utils"
import { initialize } from "../../../../src"
import { DB_URL } from "@medusajs/pricing/integration-tests/utils"
import { MedusaModule } from "@medusajs/modules-sdk"
import { IAuthenticationModuleService } from "@medusajs/types"
import { createAuthUsers } from "../../../__fixtures__/auth-user"
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
jest.setTimeout(30000)
const seedDefaultData = async (testManager) => {
await createAuthProviders(testManager)
await createAuthUsers(testManager)
}
describe("AuthenticationModuleService - AuthProvider", () => {
let service: IAuthenticationModuleService
let testManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
testManager = MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
if(service.__hooks?.onApplicationStart) {
await service.__hooks.onApplicationStart()
}
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
MedusaModule.clearInstances()
})
describe("authenticate", () => {
it("authenticate validates that a provider is registered in container", async () => {
const password = "supersecret"
const email = "test@test.com"
const passwordHash = (
await Scrypt.kdf(password, { logN: 15, r: 8, p: 1 })
).toString("base64")
await seedDefaultData(testManager)
await createAuthUsers(testManager, [
// Add authenticated user
{
provider: "usernamePassword",
entity_id: email,
provider_metadata: {
password: passwordHash,
},
},
])
const res = await service.authenticate("usernamePassword", {
body: {
email: "test@test.com",
password: password,
},
})
expect(res).toEqual({
success: true,
authUser: expect.objectContaining({
entity_id: email,
provider_metadata: {
},
}),
})
})
it("fails when no password is given", async () => {
const email = "test@test.com"
await seedDefaultData(testManager)
const res = await service.authenticate("usernamePassword", {
body: { email: "test@test.com" },
})
expect(res).toEqual({
success: false,
error: "Password should be a string",
})
})
it("fails when no email is given", async () => {
await seedDefaultData(testManager)
const res = await service.authenticate("usernamePassword", {
body: { password: "supersecret" },
})
expect(res).toEqual({
success: false,
error: "Email should be a string",
})
})
it("fails with an invalid password", async () => {
const password = "supersecret"
const email = "test@test.com"
const passwordHash = (
await Scrypt.kdf(password, { logN: 15, r: 8, p: 1 })
).toString("base64")
await seedDefaultData(testManager)
await createAuthUsers(testManager, [
// Add authenticated user
{
provider: "usernamePassword",
entity_id: email,
provider_metadata: {
password_hash: passwordHash,
},
},
])
const res = await service.authenticate("usernamePassword", {
body: {
email: "test@test.com",
password: "password",
},
})
expect(res).toEqual({
success: false,
error: "Invalid email or password",
})
})
})
})