Feat(medusa, user, core-flows): User creation with invites (#6413)
**What** - add accept invite endpoint **Invite accept flow** - authenticate using the auth endpoint to create and auth-user - invoke accept endpoint with token and info to create user
This commit is contained in:
@@ -5,6 +5,7 @@ import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||
import { useApi } from "../../../environment-helpers/use-api"
|
||||
import adminSeeder from "../../../helpers/admin-seeder"
|
||||
import { AxiosInstance } from "axios"
|
||||
import { createAdminUser } from "../../helpers/create-admin-user"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -24,7 +25,7 @@ describe("POST /admin/invites", () => {
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await createAdminUser(dbConnection, adminHeaders)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||
import { useApi } from "../../../environment-helpers/use-api"
|
||||
import adminSeeder from "../../../helpers/admin-seeder"
|
||||
import { AxiosInstance } from "axios"
|
||||
import { createAdminUser } from "../../helpers/create-admin-user"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -31,7 +32,7 @@ describe("DELETE /admin/invites/:id", () => {
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await createAdminUser(dbConnection, adminHeaders)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||
import { useApi } from "../../../environment-helpers/use-api"
|
||||
import adminSeeder from "../../../helpers/admin-seeder"
|
||||
import { AxiosInstance } from "axios"
|
||||
import { createAdminUser } from "../../helpers/create-admin-user"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -31,7 +32,7 @@ describe("GET /admin/invites", () => {
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await createAdminUser(dbConnection, adminHeaders)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||
|
||||
import { IUserModuleService } from "@medusajs/types"
|
||||
import { IAuthModuleService, IUserModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { getContainer } from "../../../environment-helpers/use-container"
|
||||
import path from "path"
|
||||
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||
import { useApi } from "../../../environment-helpers/use-api"
|
||||
import adminSeeder from "../../../helpers/admin-seeder"
|
||||
import { AxiosInstance } from "axios"
|
||||
import { createAdminUser } from "../../helpers/create-admin-user"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("GET /admin/invites/:id", () => {
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await createAdminUser(dbConnection, adminHeaders)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -48,8 +48,6 @@ describe("GET /admin/invites/:id", () => {
|
||||
it("should retrieve a single invite", async () => {
|
||||
const invite = await userModuleService.createInvites({
|
||||
email: "potential_member@test.com",
|
||||
token: "test",
|
||||
expires_at: new Date(),
|
||||
})
|
||||
|
||||
const api = useApi()! as AxiosInstance
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { IAuthModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import adminSeeder from "../../helpers/admin-seeder"
|
||||
import jwt from "jsonwebtoken"
|
||||
import { getContainer } from "../../environment-helpers/use-container"
|
||||
|
||||
export const createAdminUser = async (dbConnection, adminHeaders) => {
|
||||
await adminSeeder(dbConnection)
|
||||
const appContainer = getContainer()!
|
||||
|
||||
const authModule: IAuthModuleService = appContainer.resolve(
|
||||
ModuleRegistrationName.AUTH
|
||||
)
|
||||
const authUser = await authModule.create({
|
||||
provider: "emailpass",
|
||||
entity_id: "admin@medusa.js",
|
||||
scope: "admin",
|
||||
app_metadata: {
|
||||
user_id: "admin_user",
|
||||
},
|
||||
})
|
||||
|
||||
const token = jwt.sign(authUser, "test")
|
||||
adminHeaders.headers["authorization"] = `Bearer ${token}`
|
||||
}
|
||||
@@ -48,6 +48,9 @@ module.exports = {
|
||||
scope: "internal",
|
||||
resources: "shared",
|
||||
resolve: "@medusajs/user",
|
||||
options: {
|
||||
jwt_secret: "test",
|
||||
},
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
scope: "internal",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { InviteDTO } from "@medusajs/types"
|
||||
import { IUserModuleService } from "@medusajs/types"
|
||||
import { StepResponse } from "@medusajs/workflows-sdk"
|
||||
import { createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const validateTokenStepId = "validate-invite-token-step"
|
||||
export const validateTokenStep = createStep(
|
||||
validateTokenStepId,
|
||||
async (input: string, { container }) => {
|
||||
const userModuleService: IUserModuleService = container.resolve(
|
||||
ModuleRegistrationName.USER
|
||||
)
|
||||
|
||||
const invite = await userModuleService.validateInviteToken(input)
|
||||
|
||||
return new StepResponse(invite)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,52 @@
|
||||
import { UserDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createUsersStep } from "../../user"
|
||||
import { validateTokenStep } from "../steps/validate-token"
|
||||
import { setAuthAppMetadataStep } from "../../auth"
|
||||
import { InviteWorkflow } from "@medusajs/types"
|
||||
import { deleteInvitesStep } from "../steps"
|
||||
|
||||
export const acceptInviteWorkflowId = "accept-invite-workflow"
|
||||
export const acceptInviteWorkflow = createWorkflow(
|
||||
acceptInviteWorkflowId,
|
||||
(
|
||||
input: WorkflowData<InviteWorkflow.AcceptInviteWorkflowInputDTO>
|
||||
): WorkflowData<UserDTO[]> => {
|
||||
// validate token
|
||||
const invite = validateTokenStep(input.invite_token)
|
||||
|
||||
const createUserInput = transform(
|
||||
{ input, invite },
|
||||
({ input, invite }) => {
|
||||
return [
|
||||
{
|
||||
...input.user,
|
||||
email: invite.email,
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
const users = createUsersStep(createUserInput)
|
||||
|
||||
const authUserInput = transform({ input, users }, ({ input, users }) => {
|
||||
const createdUser = users[0]
|
||||
|
||||
return {
|
||||
authUserId: input.auth_user_id,
|
||||
key: "user_id",
|
||||
value: createdUser.id,
|
||||
}
|
||||
})
|
||||
|
||||
setAuthAppMetadataStep(authUserInput)
|
||||
|
||||
deleteInvitesStep([invite.id])
|
||||
|
||||
return users
|
||||
}
|
||||
)
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./create-invites"
|
||||
export * from "./delete-invites"
|
||||
export * from "./accept-invite"
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { acceptInviteWorkflow } from "@medusajs/core-flows"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
import { InviteWorkflow } from "@medusajs/types"
|
||||
import { AdminPostInvitesInviteAcceptReq } from "../validators"
|
||||
import { IUserModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
if (req.auth_user?.app_metadata?.user_id) {
|
||||
const moduleService: IUserModuleService = req.scope.resolve(
|
||||
ModuleRegistrationName.USER
|
||||
)
|
||||
const user = moduleService.retrieve(req.auth_user.app_metadata.user_id)
|
||||
res.status(200).json({ user })
|
||||
return
|
||||
}
|
||||
|
||||
const workflow = acceptInviteWorkflow(req.scope)
|
||||
|
||||
const input = {
|
||||
invite_token: req.filterableFields.token as string,
|
||||
auth_user_id: req.auth_user!.id,
|
||||
user: req.validatedBody as AdminPostInvitesInviteAcceptReq,
|
||||
} as InviteWorkflow.AcceptInviteWorkflowInputDTO
|
||||
|
||||
const { result: users } = await workflow.run({ input })
|
||||
|
||||
// Set customer_id on session user if we are in session
|
||||
if (req.session.auth_user) {
|
||||
req.session.auth_user.app_metadata.user_id = users[0].id
|
||||
}
|
||||
|
||||
res.status(200).json({ user: users[0] })
|
||||
}
|
||||
@@ -3,11 +3,19 @@ import {
|
||||
AdminCreateInviteRequest,
|
||||
AdminGetInvitesParams,
|
||||
AdminGetInvitesInviteParams,
|
||||
AdminPostInvitesInviteAcceptReq,
|
||||
AdminPostInvitesInviteAcceptParams,
|
||||
} from "./validators"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||
|
||||
export const adminInviteRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: "ALL",
|
||||
matcher: "/admin/invites*",
|
||||
middlewares: [authenticate("admin", ["session", "bearer"])],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/invites",
|
||||
@@ -23,6 +31,14 @@ export const adminInviteRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
matcher: "/admin/invites",
|
||||
middlewares: [transformBody(AdminCreateInviteRequest)],
|
||||
},
|
||||
{
|
||||
method: "POST",
|
||||
matcher: "/admin/invites/accept",
|
||||
middlewares: [
|
||||
transformBody(AdminPostInvitesInviteAcceptReq),
|
||||
transformQuery(AdminPostInvitesInviteAcceptParams),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/invites/:id",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { Type } from "class-transformer"
|
||||
import { IsEmail, IsOptional, IsString, ValidateNested } from "class-validator"
|
||||
import {
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import {
|
||||
DateComparisonOperator,
|
||||
FindParams,
|
||||
@@ -70,3 +76,63 @@ export class AdminCreateInviteRequest {
|
||||
@IsEmail()
|
||||
email: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Details of the use accepting the invite.
|
||||
*/
|
||||
export class AdminPostInvitesInviteAcceptUserReq {}
|
||||
|
||||
/**
|
||||
* @schema AdminPostInvitesInviteAcceptReq
|
||||
* type: object
|
||||
* description: "The details of the invite to be accepted."
|
||||
* required:
|
||||
* - token
|
||||
* - user
|
||||
* properties:
|
||||
* token:
|
||||
* description: "The token of the invite to accept. This is a unique token generated when the invite was created or resent."
|
||||
* type: string
|
||||
* user:
|
||||
* description: "The details of the user to create."
|
||||
* type: object
|
||||
* required:
|
||||
* - first_name
|
||||
* - last_name
|
||||
* - password
|
||||
* properties:
|
||||
* first_name:
|
||||
* type: string
|
||||
* description: the first name of the User
|
||||
* last_name:
|
||||
* type: string
|
||||
* description: the last name of the User
|
||||
* password:
|
||||
* description: The password for the User
|
||||
* type: string
|
||||
* format: password
|
||||
*/
|
||||
export class AdminPostInvitesInviteAcceptReq {
|
||||
/**
|
||||
* The invite's first name.
|
||||
*/
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
first_name: string
|
||||
|
||||
/**
|
||||
* The invite's last name.
|
||||
*/
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
last_name: string
|
||||
}
|
||||
|
||||
export class AdminPostInvitesInviteAcceptParams {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
token: string
|
||||
|
||||
@IsOptional()
|
||||
expand = undefined
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface CreateInviteDTO {
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateInviteDTO extends Partial<CreateInviteDTO> {
|
||||
export interface UpdateInviteDTO
|
||||
extends Partial<Omit<CreateInviteDTO, "email">> {
|
||||
id: string
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ import { IModuleService } from "../modules-sdk"
|
||||
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||
|
||||
export interface IUserModuleService extends IModuleService {
|
||||
validateInviteToken(
|
||||
token: string,
|
||||
sharedContext?: Context
|
||||
): Promise<InviteDTO>
|
||||
|
||||
retrieve(
|
||||
id: string,
|
||||
config?: FindConfig<UserDTO>,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface AcceptInviteWorkflowInputDTO {
|
||||
invite_token: string
|
||||
auth_user_id: string
|
||||
user: {
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
avatar_url?: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from "./create-invite"
|
||||
export * from "./update-invite"
|
||||
export * from "./delete-invite"
|
||||
export * from "./accept-invite"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { UpdateInviteDTO } from "../../user"
|
||||
|
||||
export interface UpdateInvitesWorkflowInputDTO {
|
||||
updates: UpdateInviteDTO[]
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export function getInitModuleConfig() {
|
||||
schema: process.env.MEDUSA_USER_DB_SCHEMA,
|
||||
},
|
||||
},
|
||||
jwt_secret: "test",
|
||||
}
|
||||
|
||||
const injectedDependencies = {}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"@mikro-orm/postgresql": "5.9.7",
|
||||
"awilix": "^8.0.0",
|
||||
"dotenv": "16.3.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"knex": "2.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as UserModuleService } from "./user-module"
|
||||
export { default as InviteService } from "./invite"
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { Context, DAL } from "@medusajs/types"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaError,
|
||||
ModulesSdkUtils,
|
||||
} from "@medusajs/utils"
|
||||
import { Invite } from "@models"
|
||||
import { InviteServiceTypes } from "@types"
|
||||
import jwt, { JwtPayload } from "jsonwebtoken"
|
||||
|
||||
type InjectedDependencies = {
|
||||
inviteRepository: DAL.RepositoryService
|
||||
}
|
||||
|
||||
// 7 days
|
||||
const DEFAULT_VALID_INVITE_DURATION = 1000 * 60 * 60 * 24 * 7
|
||||
|
||||
export default class InviteService<
|
||||
TEntity extends Invite = Invite
|
||||
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
|
||||
Invite
|
||||
)<TEntity> {
|
||||
// eslint-disable-next-line max-len
|
||||
protected readonly inviteRepository_: DAL.RepositoryService<TEntity>
|
||||
protected options_: { jwt_secret: string; valid_duration: number } | undefined
|
||||
|
||||
constructor(container: InjectedDependencies) {
|
||||
super(container)
|
||||
this.inviteRepository_ = container.inviteRepository
|
||||
}
|
||||
|
||||
public withModuleOptions(options: any) {
|
||||
const service = new InviteService<TEntity>(this.__container__)
|
||||
|
||||
service.options_ = options
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
private getOption(key: string) {
|
||||
if (!this.options_) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
`Options are not configured for InviteService, call "withModuleOptions" and provide options`
|
||||
)
|
||||
}
|
||||
return this.options_[key]
|
||||
}
|
||||
|
||||
create(
|
||||
data: InviteServiceTypes.CreateInviteDTO,
|
||||
context?: Context
|
||||
): Promise<TEntity>
|
||||
create(
|
||||
data: InviteServiceTypes.CreateInviteDTO[],
|
||||
context?: Context
|
||||
): Promise<TEntity[]>
|
||||
|
||||
@InjectTransactionManager("inviteRepository_")
|
||||
async create(
|
||||
data:
|
||||
| InviteServiceTypes.CreateInviteDTO
|
||||
| InviteServiceTypes.CreateInviteDTO[],
|
||||
context: Context = {}
|
||||
): Promise<TEntity | TEntity[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
const invites = await super.create(data_, context)
|
||||
|
||||
const expiresIn: number =
|
||||
parseInt(this.getOption("valid_duration")) ||
|
||||
DEFAULT_VALID_INVITE_DURATION
|
||||
|
||||
const updates = invites.map((invite) => {
|
||||
return {
|
||||
id: invite.id,
|
||||
expires_at: new Date().setMilliseconds(
|
||||
new Date().getMilliseconds() + expiresIn
|
||||
),
|
||||
token: this.generateToken({ id: invite.id }),
|
||||
}
|
||||
})
|
||||
|
||||
return await super.update(updates, context)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("inviteRepository_")
|
||||
async validateInviteToken(
|
||||
token: string,
|
||||
context?: Context
|
||||
): Promise<TEntity> {
|
||||
const decoded = this.validateToken(token)
|
||||
|
||||
return await super.retrieve(decoded.payload.id, {}, context)
|
||||
}
|
||||
|
||||
private generateToken(data: any): string {
|
||||
const jwtSecret: string = this.getOption("jwt_secret")
|
||||
const expiresIn: number =
|
||||
parseInt(this.getOption("valid_duration")) ||
|
||||
DEFAULT_VALID_INVITE_DURATION
|
||||
|
||||
if (!jwtSecret) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"No jwt_secret was provided in the UserModule's options. Please add one."
|
||||
)
|
||||
}
|
||||
|
||||
return jwt.sign(data, jwtSecret, {
|
||||
expiresIn,
|
||||
})
|
||||
}
|
||||
private validateToken(data: any): JwtPayload {
|
||||
const jwtSecret = this.getOption("jwt_secret")
|
||||
|
||||
if (!jwtSecret) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"No jwt_secret was provided in the UserModule's options. Please add one."
|
||||
)
|
||||
}
|
||||
|
||||
return jwt.verify(data, jwtSecret, { complete: true })
|
||||
}
|
||||
}
|
||||
@@ -10,16 +10,18 @@ import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaError,
|
||||
ModulesSdkUtils,
|
||||
} from "@medusajs/utils"
|
||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||
|
||||
import { Invite, User } from "@models"
|
||||
import InviteService from "./invite"
|
||||
|
||||
type InjectedDependencies = {
|
||||
baseRepository: DAL.RepositoryService
|
||||
userService: ModulesSdkTypes.InternalModuleService<any>
|
||||
inviteService: ModulesSdkTypes.InternalModuleService<any>
|
||||
inviteService: InviteService<any>
|
||||
}
|
||||
|
||||
const generateMethodForModels = [Invite]
|
||||
@@ -46,7 +48,7 @@ export default class UserModuleService<
|
||||
protected baseRepository_: DAL.RepositoryService
|
||||
|
||||
protected readonly userService_: ModulesSdkTypes.InternalModuleService<TUser>
|
||||
protected readonly inviteService_: ModulesSdkTypes.InternalModuleService<TInvite>
|
||||
protected readonly inviteService_: InviteService<TInvite>
|
||||
|
||||
constructor(
|
||||
{ userService, inviteService, baseRepository }: InjectedDependencies,
|
||||
@@ -57,7 +59,17 @@ export default class UserModuleService<
|
||||
|
||||
this.baseRepository_ = baseRepository
|
||||
this.userService_ = userService
|
||||
this.inviteService_ = inviteService
|
||||
this.inviteService_ = inviteService.withModuleOptions(
|
||||
this.moduleDeclaration
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async validateInviteToken(
|
||||
token: string,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<UserTypes.InviteDTO> {
|
||||
return await this.inviteService_.validateInviteToken(token, sharedContext)
|
||||
}
|
||||
|
||||
create(
|
||||
@@ -146,14 +158,11 @@ export default class UserModuleService<
|
||||
data: UserTypes.CreateInviteDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TInvite[]> {
|
||||
// expiration date in 10 days
|
||||
const expirationDate = new Date().setDate(new Date().getDate() + 10)
|
||||
|
||||
const toCreate = data.map((invite) => {
|
||||
return {
|
||||
...invite,
|
||||
expires_at: new Date(expirationDate),
|
||||
token: "placeholder", // TODO: generate token
|
||||
expires_at: new Date(),
|
||||
token: "placeholder",
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@ export type InitializeModuleInjectableDependencies = {
|
||||
logger?: Logger
|
||||
}
|
||||
|
||||
export * as ServiceTypes from "./services"
|
||||
export * from "./services"
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from "./user"
|
||||
export * as InviteServiceTypes from "./invite"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface CreateInviteDTO {
|
||||
email: string
|
||||
accepted?: boolean
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
export type UserDTO = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export type CreateUserDTO = {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export type UpdateUserDTO = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export type FilterableUserProps = {}
|
||||
@@ -46,7 +46,7 @@ export abstract class AbstractAuthModuleProvider {
|
||||
|
||||
const cloned = new (this.constructor as any)(this.container_)
|
||||
cloned.scope_ = scope
|
||||
cloned.scopeConfg_ = this.scopes_[scope]
|
||||
cloned.scopeConfig_ = this.scopes_[scope]
|
||||
|
||||
return cloned
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user