Skip to content

Commit

Permalink
feat(medusa,medusa-cli): Added an invite option to the create user co…
Browse files Browse the repository at this point in the history
…mmand, 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
  • Loading branch information
shahednasser authored Jun 7, 2023
1 parent 854022d commit 8676ee7
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changeset/tasty-walls-prove.md
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions packages/medusa-cli/src/create-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
35 changes: 35 additions & 0 deletions packages/medusa/src/commands/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ProductService,
ProductVariantService,
RegionService,
SalesChannelService,
ShippingOptionService,
ShippingProfileService,
StoreService,
Expand All @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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()
Expand Down Expand Up @@ -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")
Expand Down
25 changes: 22 additions & 3 deletions packages/medusa/src/commands/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions packages/medusa/src/services/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8676ee7

Please sign in to comment.