feat(medusa,medusa-cli): Added an invite option to the create user command, and allow seeding publishable api keys (#4192)

* feat(medusa,medusa-cli): Added an invite option to the create user command

* ensure process exits for invites

* addressed PR comments

* allow seeding publishable api keys
This commit is contained in:
Shahed Nasser
2023-06-07 21:34:27 +03:00
committed by GitHub
parent 854022daa8
commit 8676ee7a2e
5 changed files with 80 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
---
"@medusajs/medusa-cli": patch
"@medusajs/medusa": patch
---
feat(medusa,medusa-cli): Added an invite option to the create user command, and allow seeding publishable api keys

View File

@@ -296,6 +296,11 @@ function buildLocalCommands(cli, isLocalProject) {
alias: `id`,
type: `string`,
describe: `User's id.`,
})
.option(`invite`, {
type: `boolean`,
describe: `If flag is set, an invitation will be created instead of a new user and the invite token will be returned.`,
default: false,
}),
handler: handlerP(
getCommandHandler(`user`, (args, cmd) => {

View File

@@ -17,6 +17,7 @@ import {
ProductService,
ProductVariantService,
RegionService,
SalesChannelService,
ShippingOptionService,
ShippingProfileService,
StoreService,
@@ -26,6 +27,8 @@ import { ConfigModule } from "../types/global"
import { CreateProductInput } from "../types/product"
import { CreateProductCategoryInput } from "../types/product-category"
import getMigrations, { getModuleSharedResources } from "./utils/get-migrations"
import PublishableApiKeyService from "../services/publishable-api-key"
import { SalesChannel } from "../models"
type SeedOptions = {
directory: string
@@ -101,6 +104,12 @@ const seed = async function ({ directory, migrate, seedFile }: SeedOptions) {
const productCategoryService: ProductCategoryService = container.resolve(
"productCategoryService"
)
const publishableApiKeyService: PublishableApiKeyService = container.resolve(
"publishableApiKeyService"
)
const salesChannelService: SalesChannelService = container.resolve(
"salesChannelService"
)
/* eslint-disable */
const productVariantService: ProductVariantService = container.resolve(
@@ -122,6 +131,7 @@ const seed = async function ({ directory, migrate, seedFile }: SeedOptions) {
categories = [],
shipping_options,
users,
publishable_api_keys = [],
} = JSON.parse(fs.readFileSync(resolvedPath, `utf-8`))
const gcProfile = await shippingProfileService.retrieveGiftCardDefault()
@@ -235,6 +245,31 @@ const seed = async function ({ directory, migrate, seedFile }: SeedOptions) {
}
}
}
let defaultSalesChannel: SalesChannel | null = null
try {
defaultSalesChannel = await salesChannelService
.withTransaction(tx)
.retrieveDefault()
} catch (e) {
defaultSalesChannel = null
}
for (const pak of publishable_api_keys) {
const publishableApiKey = await publishableApiKeyService
.withTransaction(tx)
.create(pak, {
loggedInUserId: "",
})
// attach to default sales channel if exists
if (defaultSalesChannel) {
await publishableApiKeyService.addSalesChannels(publishableApiKey.id, [
defaultSalesChannel.id,
])
}
}
})
track("CLI_SEED_COMPLETED")

View File

@@ -5,8 +5,16 @@ import express from "express"
import { track } from "medusa-telemetry"
import loaders from "../loaders"
import Logger from "../loaders/logger"
export default async function ({ directory, id, email, password, keepAlive }) {
export default async function ({
directory,
id,
email,
password,
keepAlive,
invite,
}) {
track("CLI_USER", { with_id: !!id })
const app = express()
try {
@@ -15,8 +23,19 @@ export default async function ({ directory, id, email, password, keepAlive }) {
expressApp: app,
})
const userService = container.resolve("userService")
await userService.create({ id, email }, password)
if (invite) {
const inviteService = container.resolve("inviteService")
await inviteService.create(email, "admin")
const invite = await inviteService.list({
user_email: email,
})
Logger.info(`
Invite token: ${invite[0].token}
Open the invite in Medusa Admin at: [your-admin-url]/invite?token=${invite[0].token}`)
} else {
const userService = container.resolve("userService")
await userService.create({ id, email }, password)
}
} catch (err) {
console.error(err)
process.exit(1)

View File

@@ -177,6 +177,18 @@ class UserService extends TransactionBaseService {
}
const validatedEmail = validateEmail(user.email)
const userEntity = await userRepo.findOne({
where: { email: validatedEmail },
})
if (userEntity) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"A user with the same email already exists."
)
}
if (password) {
const hashedPassword = await this.hashPassword_(password)
createData.password_hash = hashedPassword