diff --git a/.changeset/lazy-eagles-bow.md b/.changeset/lazy-eagles-bow.md new file mode 100644 index 0000000000000..a3c1a2791f087 --- /dev/null +++ b/.changeset/lazy-eagles-bow.md @@ -0,0 +1,5 @@ +--- +"@medusajs/auth": minor +--- + +feat(auth): Migrate auth module to DML diff --git a/packages/modules/auth/src/migrations/.snapshot-medusa-auth.json b/packages/modules/auth/src/migrations/.snapshot-medusa-auth.json index c0b46de6c5fb0..491bc5a6462eb 100644 --- a/packages/modules/auth/src/migrations/.snapshot-medusa-auth.json +++ b/packages/modules/auth/src/migrations/.snapshot-medusa-auth.json @@ -1,5 +1,7 @@ { - "namespaces": ["public"], + "namespaces": [ + "public" + ], "name": "public", "tables": [ { @@ -43,14 +45,34 @@ "length": 6, "default": "now()", "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" } }, "name": "auth_identity", "schema": "public", "indexes": [ + { + "keyName": "IDX_auth_identity_deleted_at", + "columnNames": [], + "composite": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_auth_identity_deleted_at\" ON \"auth_identity\" (deleted_at) WHERE deleted_at IS NULL" + }, { "keyName": "auth_identity_pkey", - "columnNames": ["id"], + "columnNames": [ + "id" + ], "composite": false, "primary": true, "unique": true @@ -136,6 +158,16 @@ "length": 6, "default": "now()", "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" } }, "name": "provider_identity", @@ -147,7 +179,15 @@ "composite": false, "primary": false, "unique": false, - "expression": "CREATE INDEX IF NOT EXISTS \"IDX_provider_identity_auth_identity_id\" ON \"provider_identity\" (auth_identity_id)" + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_provider_identity_auth_identity_id\" ON \"provider_identity\" (auth_identity_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_provider_identity_deleted_at", + "columnNames": [], + "composite": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_provider_identity_deleted_at\" ON \"provider_identity\" (deleted_at) WHERE deleted_at IS NULL" }, { "keyName": "IDX_provider_identity_provider_entity_id", @@ -155,11 +195,13 @@ "composite": false, "primary": false, "unique": false, - "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_provider_identity_provider_entity_id\" ON \"provider_identity\" (entity_id, provider)" + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_provider_identity_provider_entity_id\" ON \"provider_identity\" (entity_id, provider) WHERE deleted_at IS NULL" }, { "keyName": "provider_identity_pkey", - "columnNames": ["id"], + "columnNames": [ + "id" + ], "composite": false, "primary": true, "unique": true @@ -169,9 +211,13 @@ "foreignKeys": { "provider_identity_auth_identity_id_foreign": { "constraintName": "provider_identity_auth_identity_id_foreign", - "columnNames": ["auth_identity_id"], + "columnNames": [ + "auth_identity_id" + ], "localTableName": "public.provider_identity", - "referencedColumnNames": ["id"], + "referencedColumnNames": [ + "id" + ], "referencedTableName": "public.auth_identity", "deleteRule": "cascade", "updateRule": "cascade" diff --git a/packages/modules/auth/src/migrations/Migration20241202100304.ts b/packages/modules/auth/src/migrations/Migration20241202100304.ts new file mode 100644 index 0000000000000..8d9a845bbb45d --- /dev/null +++ b/packages/modules/auth/src/migrations/Migration20241202100304.ts @@ -0,0 +1,31 @@ +import { Migration } from "@mikro-orm/migrations" + +export class Migration20241202100304 extends Migration { + async up(): Promise { + this.addSql( + 'alter table if exists "auth_identity" add column if not exists "deleted_at" timestamptz null;' + ) + this.addSql( + 'CREATE INDEX IF NOT EXISTS "IDX_auth_identity_deleted_at" ON "auth_identity" (deleted_at) WHERE deleted_at IS NULL;' + ) + + this.addSql( + 'alter table if exists "provider_identity" add column if not exists "deleted_at" timestamptz null;' + ) + this.addSql( + 'CREATE INDEX IF NOT EXISTS "IDX_provider_identity_deleted_at" ON "provider_identity" (deleted_at) WHERE deleted_at IS NULL;' + ) + } + + async down(): Promise { + this.addSql('drop index if exists "IDX_auth_identity_deleted_at";') + this.addSql( + 'alter table if exists "auth_identity" drop column if exists "deleted_at";' + ) + + this.addSql('drop index if exists "IDX_provider_identity_deleted_at";') + this.addSql( + 'alter table if exists "provider_identity" drop column if exists "deleted_at";' + ) + } +} diff --git a/packages/modules/auth/src/models/auth-identity.ts b/packages/modules/auth/src/models/auth-identity.ts index 00c77483a9369..e547423fceccc 100644 --- a/packages/modules/auth/src/models/auth-identity.ts +++ b/packages/modules/auth/src/models/auth-identity.ts @@ -1,45 +1,14 @@ -import { - BeforeCreate, - Collection, - Entity, - OneToMany, - OnInit, - PrimaryKey, - Property, -} from "@mikro-orm/core" - -import { generateEntityId } from "@medusajs/framework/utils" -import ProviderIdentity from "./provider-identity" - -@Entity() -export default class AuthIdentity { - @PrimaryKey({ columnType: "text" }) - id!: string - - @OneToMany(() => ProviderIdentity, (o) => o.auth_identity) - provider_identities = new Collection(this) - - @Property({ columnType: "jsonb", nullable: true }) - app_metadata: Record | null - - @Property({ - onCreate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", +import { model } from "@medusajs/framework/utils" +import { ProviderIdentity } from "./provider-identity" + +export const AuthIdentity = model + .define("auth_identity", { + id: model.id({ prefix: "authid" }).primaryKey(), + provider_identities: model.hasMany(() => ProviderIdentity, { + mappedBy: "auth_identity", + }), + app_metadata: model.json().nullable(), }) - created_at: Date - - @Property({ - onCreate: () => new Date(), - onUpdate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", + .cascades({ + delete: ["provider_identities"], }) - updated_at: Date - - @BeforeCreate() - @OnInit() - onCreate() { - this.id = generateEntityId(this.id, "authid") - } -} diff --git a/packages/modules/auth/src/models/index.ts b/packages/modules/auth/src/models/index.ts index dd39d3deb5154..15d37290b5978 100644 --- a/packages/modules/auth/src/models/index.ts +++ b/packages/modules/auth/src/models/index.ts @@ -1,2 +1,2 @@ -export { default as AuthIdentity } from "./auth-identity" -export { default as ProviderIdentity } from "./provider-identity" +export { AuthIdentity } from "./auth-identity" +export { ProviderIdentity } from "./provider-identity" diff --git a/packages/modules/auth/src/models/provider-identity.ts b/packages/modules/auth/src/models/provider-identity.ts index 130f1a4fdef3c..6f1ed6d874718 100644 --- a/packages/modules/auth/src/models/provider-identity.ts +++ b/packages/modules/auth/src/models/provider-identity.ts @@ -1,85 +1,21 @@ -import { - BeforeCreate, - Entity, - ManyToOne, - OnInit, - PrimaryKey, - Property, - Rel, -} from "@mikro-orm/core" - -import { - createPsqlIndexStatementHelper, - generateEntityId, -} from "@medusajs/framework/utils" -import AuthIdentity from "./auth-identity" - -const providerEntityIdIndexName = "IDX_provider_identity_provider_entity_id" -const providerEntityIdIndexStatement = createPsqlIndexStatementHelper({ - name: providerEntityIdIndexName, - tableName: "provider_identity", - columns: ["entity_id", "provider"], - unique: true, -}) - -const authIdentityIndexName = "IDX_provider_identity_auth_identity_id" -const authIdentityIndexStatement = createPsqlIndexStatementHelper({ - name: authIdentityIndexName, - tableName: "provider_identity", - columns: ["auth_identity_id"], -}) - -@Entity() -@providerEntityIdIndexStatement.MikroORMIndex() -@authIdentityIndexStatement.MikroORMIndex() -export default class ProviderIdentity { - @PrimaryKey({ columnType: "text" }) - id!: string - - @Property({ columnType: "text" }) - entity_id: string - - @Property({ columnType: "text" }) - provider: string - - @ManyToOne(() => AuthIdentity, { - columnType: "text", - fieldName: "auth_identity_id", - mapToPk: true, - onDelete: "cascade", - }) - auth_identity_id: string - - @ManyToOne(() => AuthIdentity, { - persist: false, - }) - auth_identity: Rel - - @Property({ columnType: "jsonb", nullable: true }) - user_metadata: Record | null - - @Property({ columnType: "jsonb", nullable: true }) - provider_metadata: Record | null = null - - @Property({ - onCreate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", - }) - created_at: Date - - @Property({ - onCreate: () => new Date(), - onUpdate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", +import { model } from "@medusajs/framework/utils" +import { AuthIdentity } from "./auth-identity" + +export const ProviderIdentity = model + .define("provider_identity", { + id: model.id().primaryKey(), + entity_id: model.text(), + provider: model.text(), + auth_identity: model.belongsTo(() => AuthIdentity, { + mappedBy: "provider_identities", + }), + user_metadata: model.json().nullable(), + provider_metadata: model.json().nullable(), }) - updated_at: Date - - @BeforeCreate() - @OnInit() - onCreate() { - this.id = generateEntityId(this.id, "provid") - this.auth_identity_id ??= this.auth_identity?.id ?? null - } -} + .indexes([ + { + name: "IDX_provider_identity_provider_entity_id", + on: ["entity_id", "provider"], + unique: true, + }, + ]) diff --git a/packages/modules/auth/src/services/auth-module.ts b/packages/modules/auth/src/services/auth-module.ts index 6a314989e3ec8..de94b9c8754ff 100644 --- a/packages/modules/auth/src/services/auth-module.ts +++ b/packages/modules/auth/src/services/auth-module.ts @@ -5,6 +5,7 @@ import { AuthTypes, Context, DAL, + InferEntityType, InternalModuleDeclaration, Logger, ModuleJoinerConfig, @@ -35,8 +36,12 @@ export default class AuthModuleService implements AuthTypes.IAuthModuleService { protected baseRepository_: DAL.RepositoryService - protected authIdentityService_: ModulesSdkTypes.IMedusaInternalService - protected providerIdentityService_: ModulesSdkTypes.IMedusaInternalService + protected authIdentityService_: ModulesSdkTypes.IMedusaInternalService< + InferEntityType + > + protected providerIdentityService_: ModulesSdkTypes.IMedusaInternalService< + InferEntityType + > protected readonly authProviderService_: AuthProviderService constructor(