Skip to content

Commit

Permalink
feat(types,module-sdk): setup authentication module skeleton (#5943)
Browse files Browse the repository at this point in the history
**What**
- add authentication module skeleton
  • Loading branch information
pKorsholm authored Dec 21, 2023
1 parent 3f6d799 commit 6d1e3cc
Show file tree
Hide file tree
Showing 44 changed files with 720 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/angry-pigs-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@medusajs/modules-sdk": patch
"@medusajs/types": patch
---

feat(modules-sdk, types): add initial authentication module configuration
6 changes: 6 additions & 0 deletions packages/authentication/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/dist
node_modules
.DS_store
.env*
.env
*.sql
Empty file.
3 changes: 3 additions & 0 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Authentication Module

The Authentication Module is Medusa’s authentication engine engine. It provides functions to authenticate users through identity providers and store metadata about users that can be used for authorization purposes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("Noop test", () => {
it("noop check", async () => {
expect(true).toBe(true)
})
})
6 changes: 6 additions & 0 deletions packages/authentication/integration-tests/setup-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
if (typeof process.env.DB_TEMP_NAME === "undefined") {
const tempName = parseInt(process.env.JEST_WORKER_ID || "1")
process.env.DB_TEMP_NAME = `medusa-authentication-integration-${tempName}`
}

process.env.MEDUSA_AUTHENTICATION_DB_SCHEMA = "public"
3 changes: 3 additions & 0 deletions packages/authentication/integration-tests/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { JestUtils } from "medusa-test-utils"

JestUtils.afterAllHookDropDatabase()
6 changes: 6 additions & 0 deletions packages/authentication/integration-tests/utils/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ModuleServiceInitializeOptions } from "@medusajs/types"

export const databaseOptions: ModuleServiceInitializeOptions["database"] = {
schema: "public",
clientUrl: "medusa-authentication-test",
}
18 changes: 18 additions & 0 deletions packages/authentication/integration-tests/utils/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { TestDatabaseUtils } from "medusa-test-utils"

import * as AuthenticationModels from "@models"

const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = AuthenticationModels as unknown as any[]

export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper(
mikroOrmEntities,
pathToMigrations
)

export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig(
mikroOrmEntities,
pathToMigrations
)

export const DB_URL = TestDatabaseUtils.getDatabaseURL()
2 changes: 2 additions & 0 deletions packages/authentication/integration-tests/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./config"
export * from "./database"
21 changes: 21 additions & 0 deletions packages/authentication/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
moduleNameMapper: {
"^@models": "<rootDir>/src/models",
"^@services": "<rootDir>/src/services",
"^@repositories": "<rootDir>/src/repositories",
},
transform: {
"^.+\\.[jt]s?$": [
"ts-jest",
{
tsConfig: "tsconfig.spec.json",
isolatedModules: true,
},
],
},
testEnvironment: `node`,
moduleFileExtensions: [`js`, `ts`],
modulePathIgnorePatterns: ["dist/"],
setupFiles: ["<rootDir>/integration-tests/setup-env.js"],
setupFilesAfterEnv: ["<rootDir>/integration-tests/setup.js"],
}
8 changes: 8 additions & 0 deletions packages/authentication/mikro-orm.config.dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as entities from "./src/models"

module.exports = {
entities: Object.values(entities),
schema: "public",
clientUrl: "postgres://postgres@localhost/medusa-authentication",
type: "postgresql",
}
63 changes: 63 additions & 0 deletions packages/authentication/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"name": "@medusajs/authentication",
"version": "0.0.1",
"description": "Medusa Authentication module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"engines": {
"node": ">=16"
},
"bin": {
"medusa-authentication-migrations-down": "dist/scripts/bin/run-migration-down.js",
"medusa-authentication-migrations-up": "dist/scripts/bin/run-migration-up.js",
"medusa-authentication-seed": "dist/scripts/bin/run-seed.js"
},
"repository": {
"type": "git",
"url": "https://github.com/medusajs/medusa",
"directory": "packages/authentication"
},
"publishConfig": {
"access": "public"
},
"author": "Medusa",
"license": "MIT",
"scripts": {
"watch": "tsc --build --watch",
"watch:test": "tsc --build tsconfig.spec.json --watch",
"prepublishOnly": "cross-env NODE_ENV=production tsc --build && tsc-alias -p tsconfig.json",
"build": "rimraf dist && tsc --build && tsc-alias -p tsconfig.json",
"test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts",
"test:integration": "jest --runInBand --forceExit -- integration-tests/**/__tests__/**/*.ts",
"migration:generate": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:generate",
"migration:initial": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create --initial",
"migration:create": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create",
"migration:up": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:up",
"orm:cache:clear": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm cache:clear"
},
"devDependencies": {
"@mikro-orm/cli": "5.7.12",
"cross-env": "^5.2.1",
"jest": "^29.6.3",
"medusa-test-utils": "^1.1.40",
"rimraf": "^3.0.2",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tsc-alias": "^1.8.6",
"typescript": "^5.1.6"
},
"dependencies": {
"@medusajs/modules-sdk": "^1.12.5",
"@medusajs/types": "^1.11.9",
"@medusajs/utils": "^1.11.2",
"@mikro-orm/core": "5.7.12",
"@mikro-orm/migrations": "5.7.12",
"@mikro-orm/postgresql": "5.7.12",
"awilix": "^8.0.0",
"dotenv": "^16.1.4",
"knex": "2.4.2"
}
}
7 changes: 7 additions & 0 deletions packages/authentication/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { moduleDefinition } from "./module-definition"

export default moduleDefinition

export * from "./initialize"
export * from "./loaders"
export * from "./scripts"
27 changes: 27 additions & 0 deletions packages/authentication/src/initialize/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
ExternalModuleDeclaration,
InternalModuleDeclaration,
MedusaModule,
MODULE_PACKAGE_NAMES,
Modules,
} from "@medusajs/modules-sdk"
import { IAuthenticationModuleService, ModulesSdkTypes } from "@medusajs/types"
import { moduleDefinition } from "../module-definition"
import { InitializeModuleInjectableDependencies } from "../types"

export const initialize = async (
options?: ModulesSdkTypes.ModuleBootstrapDeclaration,
injectedDependencies?: InitializeModuleInjectableDependencies
): Promise<IAuthenticationModuleService> => {
const loaded = await MedusaModule.bootstrap<IAuthenticationModuleService>({
moduleKey: Modules.AUTHENTICATION,
defaultPath: MODULE_PACKAGE_NAMES[Modules.AUTHENTICATION],
declaration: options as
| InternalModuleDeclaration
| ExternalModuleDeclaration, // TODO: Add provider configuration
injectedDependencies,
moduleExports: moduleDefinition,
})

return loaded[Modules.AUTHENTICATION]
}
31 changes: 31 additions & 0 deletions packages/authentication/src/joiner-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { AuthUser } from "@models"

export const LinkableKeys = {
auth_user_id: AuthUser.name,
}

const entityLinkableKeysMap: MapToConfig = {}
Object.entries(LinkableKeys).forEach(([key, value]) => {
entityLinkableKeysMap[value] ??= []
entityLinkableKeysMap[value].push({
mapTo: key,
valueFrom: key.split("_").pop()!,
})
})

export const entityNameToLinkableKeysMap: MapToConfig = entityLinkableKeysMap

export const joinerConfig: ModuleJoinerConfig = {
serviceName: Modules.AUTHENTICATION,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
alias: {
name: ["auth_user", "auth_users"],
args: {
entity: AuthUser.name,
},
},
}
36 changes: 36 additions & 0 deletions packages/authentication/src/loaders/connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
InternalModuleDeclaration,
LoaderOptions,
Modules,
} from "@medusajs/modules-sdk"
import { ModulesSdkTypes } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { EntitySchema } from "@mikro-orm/core"
import * as AuthenticationModules from "../models"

export default async (
{
options,
container,
logger,
}: LoaderOptions<
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
>,
moduleDeclaration?: InternalModuleDeclaration
): Promise<void> => {
const entities = Object.values(
AuthenticationModules
) as unknown as EntitySchema[]
const pathToMigrations = __dirname + "/../migrations"

await ModulesSdkUtils.mikroOrmConnectionLoader({
moduleName: Modules.AUTHENTICATION,
entities,
container,
options,
moduleDeclaration,
logger,
pathToMigrations,
})
}
38 changes: 38 additions & 0 deletions packages/authentication/src/loaders/container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as defaultRepositories from "@repositories"

import { LoaderOptions } from "@medusajs/modules-sdk"
import { ModulesSdkTypes } from "@medusajs/types"
import { loadCustomRepositories } from "@medusajs/utils"
import { asClass } from "awilix"

export default async ({
container,
options,
}: LoaderOptions<
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
>): Promise<void> => {
const customRepositories = (
options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
)?.repositories

container.register({
// authenticationService: asClass(defaultServices.AuthenticationService).singleton(),
})

if (customRepositories) {
loadCustomRepositories({
defaultRepositories,
customRepositories,
container,
})
} else {
loadDefaultRepositories({ container })
}
}

function loadDefaultRepositories({ container }) {
container.register({
baseRepository: asClass(defaultRepositories.BaseRepository).singleton(),
})
}
2 changes: 2 additions & 0 deletions packages/authentication/src/loaders/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./connection"
export * from "./container"
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"namespaces": [
"public"
],
"name": "public",
"tables": [
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
}
},
"name": "auth_user",
"schema": "public",
"indexes": [
{
"keyName": "auth_user_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {}
}
]
}
13 changes: 13 additions & 0 deletions packages/authentication/src/migrations/Migration20231220132440.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Migration } from '@mikro-orm/migrations';

export class Migration20231220132440 extends Migration {

async up(): Promise<void> {
this.addSql('create table "auth_user" ("id" text not null, constraint "auth_user_pkey" primary key ("id"));');
}

async down(): Promise<void> {
this.addSql('drop table if exists "auth_user" cascade;');
}

}
18 changes: 18 additions & 0 deletions packages/authentication/src/models/auth-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { generateEntityId } from "@medusajs/utils"
import { BeforeCreate, Entity, OnInit, PrimaryKey } from "@mikro-orm/core"

@Entity()
export default class AuthUser {
@PrimaryKey({ columnType: "text" })
id!: string

@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "authusr")
}

@OnInit()
onInit() {
this.id = generateEntityId(this.id, "authusr")
}
}
1 change: 1 addition & 0 deletions packages/authentication/src/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as AuthUser } from "./auth-user"
12 changes: 12 additions & 0 deletions packages/authentication/src/module-definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ModuleExports } from "@medusajs/types"
import { AuthenticationModuleService } from "@services"
import loadConnection from "./loaders/connection"
import loadContainer from "./loaders/container"

const service = AuthenticationModuleService
const loaders = [loadContainer, loadConnection] as any

export const moduleDefinition: ModuleExports = {
service,
loaders,
}
1 change: 1 addition & 0 deletions packages/authentication/src/repositories/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils"
Loading

0 comments on commit 6d1e3cc

Please sign in to comment.