feat(authentication): Google authentication provider (#6104)
* init * add entity_id and update provider * initial implementation * update lockfile * fix conflicts * add config variables * update types * refactor google provider * re-order methods * fix pr feedback p. 1 * add initial type and update callback authorization * add google provider to integration test * fix feedback * initial implementation (#6171) * initial implementation * remove oauth lib * move abstract authentication provider * shuffle files around * Update packages/authentication/src/migrations/Migration20240122041959.ts Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> * call verify with token --------- Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
|
||||
import { MikroOrmWrapper } from "../../../utils"
|
||||
import { initialize } from "../../../../src"
|
||||
import { DB_URL } from "@medusajs/pricing/integration-tests/utils"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import { IAuthenticationModuleService } from "@medusajs/types"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import { MikroOrmWrapper } from "../../../utils"
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
|
||||
import { initialize } from "../../../../src"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
@@ -24,7 +23,7 @@ describe("AuthenticationModuleService - AuthProvider", () => {
|
||||
},
|
||||
})
|
||||
|
||||
if(service.__hooks?.onApplicationStart) {
|
||||
if (service.__hooks?.onApplicationStart) {
|
||||
await service.__hooks.onApplicationStart()
|
||||
}
|
||||
})
|
||||
@@ -39,12 +38,18 @@ describe("AuthenticationModuleService - AuthProvider", () => {
|
||||
const authProviders = await service.listAuthProviders()
|
||||
const serialized = JSON.parse(JSON.stringify(authProviders))
|
||||
|
||||
expect(serialized).toEqual([
|
||||
expect.objectContaining({
|
||||
provider: "usernamePassword",
|
||||
name: "Username/Password Authentication",
|
||||
}),
|
||||
])
|
||||
expect(serialized).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
provider: "usernamePassword",
|
||||
name: "Username/Password Authentication",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
provider: "google",
|
||||
name: "Google Authentication",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import Scrypt from "scrypt-kdf"
|
||||
|
||||
import { MikroOrmWrapper } from "../../../utils"
|
||||
import { initialize } from "../../../../src"
|
||||
import { DB_URL } from "@medusajs/pricing/integration-tests/utils"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import { IAuthenticationModuleService } from "@medusajs/types"
|
||||
import { createAuthUsers } from "../../../__fixtures__/auth-user"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import { MikroOrmWrapper } from "../../../utils"
|
||||
import Scrypt from "scrypt-kdf"
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import { createAuthProviders } from "../../../__fixtures__/auth-provider"
|
||||
import { createAuthUsers } from "../../../__fixtures__/auth-user"
|
||||
import { initialize } from "../../../../src"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
const seedDefaultData = async (testManager) => {
|
||||
|
||||
@@ -56,7 +56,9 @@
|
||||
"@mikro-orm/postgresql": "5.9.7",
|
||||
"awilix": "^8.0.0",
|
||||
"dotenv": "^16.1.4",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"knex": "2.4.2",
|
||||
"scrypt-kdf": "^2.0.1"
|
||||
"scrypt-kdf": "^2.0.1",
|
||||
"simple-oauth2": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import * as defaultProviders from "@providers"
|
||||
|
||||
import {
|
||||
AwilixContainer,
|
||||
ClassOrFunctionReturning,
|
||||
Constructor,
|
||||
Resolver,
|
||||
asClass,
|
||||
} from "awilix"
|
||||
import { LoaderOptions, ModulesSdkTypes } from "@medusajs/types"
|
||||
|
||||
import { AwilixContainer, ClassOrFunctionReturning, Resolver, asClass, asFunction, asValue } from "awilix"
|
||||
|
||||
export default async ({
|
||||
container,
|
||||
}: LoaderOptions<
|
||||
@@ -18,7 +23,9 @@ export default async ({
|
||||
|
||||
for (const provider of providersToLoad) {
|
||||
container.register({
|
||||
[`auth_provider_${provider.PROVIDER}`]: asClass(provider).singleton(),
|
||||
[`auth_provider_${provider.PROVIDER}`]: asClass(
|
||||
provider as Constructor<any>
|
||||
).singleton(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,15 @@
|
||||
],
|
||||
"mappedType": "enum"
|
||||
},
|
||||
"config": {
|
||||
"name": "config",
|
||||
"type": "jsonb",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": true,
|
||||
"mappedType": "json"
|
||||
},
|
||||
"is_active": {
|
||||
"name": "is_active",
|
||||
"type": "boolean",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20240104154451 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('create table "auth_provider" ("provider" text not null, "name" text not null, "domain" text check ("domain" in (\'all\', \'store\', \'admin\')) not null default \'all\', "is_active" boolean not null default false, constraint "auth_provider_pkey" primary key ("provider"));');
|
||||
|
||||
this.addSql('create table "auth_user" ("id" text not null, "provider_id" text null, "user_metadata" jsonb null, "app_metadata" jsonb null, "provider_metadata" jsonb null, constraint "auth_user_pkey" primary key ("id"));');
|
||||
|
||||
this.addSql('alter table "auth_user" add constraint "auth_user_provider_id_foreign" foreign key ("provider_id") references "auth_provider" ("provider") on delete cascade;');
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql('alter table "auth_user" drop constraint "auth_user_provider_id_foreign";');
|
||||
|
||||
this.addSql('drop table if exists "auth_provider" cascade;');
|
||||
|
||||
this.addSql('drop table if exists "auth_user" cascade;');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20240115092929 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('alter table "auth_user" add column "entity_id" text not null;');
|
||||
this.addSql('alter table "auth_user" add constraint "IDX_auth_user_provider_entity_id" unique ("provider_id", "entity_id");');
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql('alter table "auth_user" drop constraint "IDX_auth_user_provider_entity_id";');
|
||||
this.addSql('alter table "auth_user" drop column "entity_id";');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20240122041959 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('create table if not exists "auth_provider" ("provider" text not null, "name" text not null, "domain" text check ("domain" in (\'all\', \'store\', \'admin\')) not null default \'all\', "config" jsonb null, "is_active" boolean not null default false, constraint "auth_provider_pkey" primary key ("provider"));');
|
||||
|
||||
this.addSql('create table if not exists "auth_user" ("id" text not null, "entity_id" text not null, "provider_id" text null, "user_metadata" jsonb null, "app_metadata" jsonb null, "provider_metadata" jsonb null, constraint "auth_user_pkey" primary key ("id"));');
|
||||
this.addSql('alter table "auth_user" add constraint "IDX_auth_user_provider_entity_id" unique ("provider_id", "entity_id");');
|
||||
|
||||
this.addSql('alter table "auth_user" add constraint if not exists "auth_user_provider_id_foreign" foreign key ("provider_id") references "auth_provider" ("provider") on delete cascade;');
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql('alter table "auth_user" drop constraint if exists "auth_user_provider_id_foreign";');
|
||||
|
||||
this.addSql('drop table if exists "auth_provider" cascade;');
|
||||
|
||||
this.addSql('drop table if exists "auth_user" cascade;');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,9 +5,10 @@ import {
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
|
||||
import { ProviderDomain } from "../types/repositories/auth-provider"
|
||||
|
||||
type OptionalFields = "domain" | "is_active"
|
||||
type OptionalFields = "domain" | "is_active" | "config"
|
||||
|
||||
@Entity()
|
||||
export default class AuthProvider {
|
||||
@@ -22,6 +23,9 @@ export default class AuthProvider {
|
||||
@Enum({ items: () => ProviderDomain, default: ProviderDomain.ALL })
|
||||
domain: ProviderDomain = ProviderDomain.ALL
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
config: Record<string, unknown> | null = null
|
||||
|
||||
@Property({ columnType: "boolean", default: false })
|
||||
is_active = false
|
||||
}
|
||||
|
||||
209
packages/authentication/src/providers/google.ts
Normal file
209
packages/authentication/src/providers/google.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import {
|
||||
AbstractAuthenticationModuleProvider,
|
||||
MedusaError,
|
||||
} from "@medusajs/utils"
|
||||
import { AuthProviderService, AuthUserService } from "@services"
|
||||
import jwt, { JwtPayload } from "jsonwebtoken"
|
||||
|
||||
import { AuthProvider } from "@models"
|
||||
import { AuthenticationResponse } from "@medusajs/types"
|
||||
import { AuthorizationCode } from "simple-oauth2"
|
||||
import url from "url"
|
||||
|
||||
type InjectedDependencies = {
|
||||
authUserService: AuthUserService
|
||||
authProviderService: AuthProviderService
|
||||
}
|
||||
|
||||
type AuthenticationInput = {
|
||||
connection: { encrypted: boolean }
|
||||
url: string
|
||||
headers: { host: string }
|
||||
query: Record<string, string>
|
||||
body: Record<string, string>
|
||||
}
|
||||
|
||||
type ProviderConfig = {
|
||||
clientID: string
|
||||
clientSecret: string
|
||||
callbackURL: string
|
||||
}
|
||||
|
||||
class GoogleProvider extends AbstractAuthenticationModuleProvider {
|
||||
public static PROVIDER = "google"
|
||||
public static DISPLAY_NAME = "Google Authentication"
|
||||
|
||||
protected readonly authUserSerivce_: AuthUserService
|
||||
protected readonly authProviderService_: AuthProviderService
|
||||
|
||||
constructor({ authUserService, authProviderService }: InjectedDependencies) {
|
||||
super()
|
||||
|
||||
this.authUserSerivce_ = authUserService
|
||||
this.authProviderService_ = authProviderService
|
||||
}
|
||||
|
||||
private async validateConfig(config: Partial<ProviderConfig>) {
|
||||
if (!config.clientID) {
|
||||
throw new Error("Google clientID is required")
|
||||
}
|
||||
|
||||
if (!config.clientSecret) {
|
||||
throw new Error("Google clientSecret is required")
|
||||
}
|
||||
|
||||
if (!config.callbackURL) {
|
||||
throw new Error("Google callbackUrl is required")
|
||||
}
|
||||
}
|
||||
|
||||
private originalURL(req: AuthenticationInput) {
|
||||
const tls = req.connection.encrypted,
|
||||
host = req.headers.host,
|
||||
protocol = tls ? "https" : "http",
|
||||
path = req.url || ""
|
||||
return protocol + "://" + host + path
|
||||
}
|
||||
|
||||
async getProviderConfig(req: AuthenticationInput): Promise<ProviderConfig> {
|
||||
const { config } = (await this.authProviderService_.retrieve(
|
||||
GoogleProvider.PROVIDER
|
||||
)) as AuthProvider & { config: ProviderConfig }
|
||||
|
||||
this.validateConfig(config || {})
|
||||
|
||||
const { callbackURL } = config
|
||||
|
||||
const parsedCallbackUrl = !url.parse(callbackURL).protocol
|
||||
? url.resolve(this.originalURL(req), callbackURL)
|
||||
: callbackURL
|
||||
|
||||
return { ...config, callbackURL: parsedCallbackUrl }
|
||||
}
|
||||
|
||||
async authenticate(
|
||||
req: AuthenticationInput
|
||||
): Promise<AuthenticationResponse> {
|
||||
if (req.query && req.query.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: `${req.query.error_description}, read more at: ${req.query.error_uri}`,
|
||||
}
|
||||
}
|
||||
|
||||
let config
|
||||
|
||||
try {
|
||||
config = await this.getProviderConfig(req)
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message }
|
||||
}
|
||||
|
||||
let { callbackURL, clientID, clientSecret } = config
|
||||
|
||||
const meta: ProviderConfig = {
|
||||
clientID,
|
||||
callbackURL,
|
||||
clientSecret,
|
||||
}
|
||||
|
||||
const code = (req.query && req.query.code) || (req.body && req.body.code)
|
||||
|
||||
// Redirect to google
|
||||
if (!code) {
|
||||
return this.getRedirect(meta)
|
||||
}
|
||||
|
||||
return await this.validateCallback(code, meta)
|
||||
}
|
||||
|
||||
// abstractable
|
||||
private async validateCallback(
|
||||
code: string,
|
||||
{ clientID, callbackURL, clientSecret }: ProviderConfig
|
||||
) {
|
||||
const client = this.getAuthorizationCodeHandler({ clientID, clientSecret })
|
||||
|
||||
const tokenParams = {
|
||||
code,
|
||||
redirect_uri: callbackURL,
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = await client.getToken(tokenParams)
|
||||
|
||||
return await this.verify_(accessToken.token.id_token)
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message }
|
||||
}
|
||||
}
|
||||
|
||||
// abstractable
|
||||
async verify_(refreshToken: string) {
|
||||
const jwtData = (await jwt.decode(refreshToken, {
|
||||
complete: true,
|
||||
})) as JwtPayload
|
||||
const entity_id = jwtData.payload.email
|
||||
|
||||
let authUser
|
||||
|
||||
try {
|
||||
authUser = await this.authUserSerivce_.retrieveByProviderAndEntityId(
|
||||
entity_id,
|
||||
GoogleProvider.PROVIDER
|
||||
)
|
||||
} catch (error) {
|
||||
if (error.type === MedusaError.Types.NOT_FOUND) {
|
||||
authUser = await this.authUserSerivce_.create([
|
||||
{
|
||||
entity_id,
|
||||
provider_id: GoogleProvider.PROVIDER,
|
||||
user_metadata: jwtData!.payload,
|
||||
},
|
||||
])
|
||||
} else {
|
||||
return { success: false, error: error.message }
|
||||
}
|
||||
}
|
||||
|
||||
return { success: true, authUser }
|
||||
}
|
||||
|
||||
// Abstractable
|
||||
private getRedirect({ clientID, callbackURL, clientSecret }: ProviderConfig) {
|
||||
const client = this.getAuthorizationCodeHandler({ clientID, clientSecret })
|
||||
|
||||
const location = client.authorizeURL({
|
||||
redirect_uri: callbackURL,
|
||||
scope: "email profile",
|
||||
})
|
||||
|
||||
return { success: true, location }
|
||||
}
|
||||
|
||||
private getAuthorizationCodeHandler({
|
||||
clientID,
|
||||
clientSecret,
|
||||
}: {
|
||||
clientID: string
|
||||
clientSecret: string
|
||||
}) {
|
||||
const config = {
|
||||
client: {
|
||||
id: clientID,
|
||||
secret: clientSecret,
|
||||
},
|
||||
auth: {
|
||||
// TODO: abstract to not be google specific
|
||||
authorizeHost: "https://accounts.google.com",
|
||||
authorizePath: "/o/oauth2/v2/auth",
|
||||
tokenHost: "https://www.googleapis.com",
|
||||
tokenPath: "/oauth2/v4/token",
|
||||
},
|
||||
}
|
||||
|
||||
return new AuthorizationCode(config)
|
||||
}
|
||||
}
|
||||
|
||||
export default GoogleProvider
|
||||
@@ -1 +1,2 @@
|
||||
export { default as UsernamePasswordProvider } from "./username-password"
|
||||
export { default as GoogleProvider } from "./google"
|
||||
@@ -1,11 +1,8 @@
|
||||
import {
|
||||
AbstractAuthenticationModuleProvider,
|
||||
AuthenticationResponse,
|
||||
} from "@medusajs/types"
|
||||
import { AuthenticationResponse } from "@medusajs/types"
|
||||
|
||||
import { AuthUserService } from "@services"
|
||||
import Scrypt from "scrypt-kdf"
|
||||
import { isString } from "@medusajs/utils"
|
||||
import { AbstractAuthenticationModuleProvider, isString } from "@medusajs/utils"
|
||||
|
||||
class UsernamePasswordProvider extends AbstractAuthenticationModuleProvider {
|
||||
public static PROVIDER = "usernamePassword"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
AbstractAuthenticationModuleProvider,
|
||||
AuthenticationResponse,
|
||||
AuthenticationTypes,
|
||||
Context,
|
||||
@@ -16,6 +15,7 @@ import { joinerConfig } from "../joiner-config"
|
||||
import { AuthProviderService, AuthUserService } from "@services"
|
||||
|
||||
import {
|
||||
AbstractAuthenticationModuleProvider,
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
@@ -158,7 +158,7 @@ export default class AuthenticationModuleService<
|
||||
protected async createAuthProviders_(
|
||||
data: any[],
|
||||
@MedusaContext() sharedContext: Context
|
||||
): Promise<AuthenticationTypes.AuthProviderDTO[]> {
|
||||
): Promise<TAuthProvider[]> {
|
||||
return await this.authProviderService_.create(data, sharedContext)
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ export default class AuthenticationModuleService<
|
||||
async updateAuthProvider_(
|
||||
data: AuthenticationTypes.UpdateAuthProviderDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<AuthProviderDTO[]> {
|
||||
): Promise<TAuthProvider[]> {
|
||||
return await this.authProviderService_.update(data, sharedContext)
|
||||
}
|
||||
|
||||
@@ -380,15 +380,14 @@ export default class AuthenticationModuleService<
|
||||
await this.retrieveAuthProvider(provider, {})
|
||||
|
||||
registeredProvider = this.getRegisteredAuthenticationProvider(provider)
|
||||
|
||||
|
||||
return await registeredProvider.authenticate(authenticationData)
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async createProvidersOnLoad() {
|
||||
private async createProvidersOnLoad() {
|
||||
const providersToLoad = this.__container__["auth_providers"]
|
||||
|
||||
const providers = await this.authProviderService_.list({
|
||||
|
||||
@@ -5,6 +5,7 @@ export type CreateAuthProviderDTO = {
|
||||
name: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type UpdateAuthProviderDTO = {
|
||||
@@ -13,6 +14,7 @@ export type UpdateAuthProviderDTO = {
|
||||
name?: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
provider: AuthProvider
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ export type AuthProviderDTO = {
|
||||
name: string
|
||||
domain: ProviderDomain
|
||||
is_active: boolean
|
||||
config: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type CreateAuthProviderDTO = {
|
||||
@@ -10,6 +11,7 @@ export type CreateAuthProviderDTO = {
|
||||
name: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type UpdateAuthProviderDTO = {
|
||||
@@ -17,6 +19,7 @@ export type UpdateAuthProviderDTO = {
|
||||
name?: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export enum ProviderDomain {
|
||||
|
||||
@@ -5,6 +5,7 @@ export type AuthProviderDTO = {
|
||||
name: string
|
||||
domain: ProviderDomain
|
||||
is_active: boolean
|
||||
config: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export type CreateAuthProviderDTO = {
|
||||
@@ -12,6 +13,7 @@ export type CreateAuthProviderDTO = {
|
||||
name: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type UpdateAuthProviderDTO = {
|
||||
@@ -19,6 +21,7 @@ export type UpdateAuthProviderDTO = {
|
||||
name?: string
|
||||
domain?: ProviderDomain
|
||||
is_active?: boolean
|
||||
config?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export enum ProviderDomain {
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./auth-user"
|
||||
export * from "./auth-provider"
|
||||
export * from "./provider"
|
||||
|
||||
5
packages/types/src/authentication/common/provider.ts
Normal file
5
packages/types/src/authentication/common/provider.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export type AuthenticationResponse = {
|
||||
success: boolean
|
||||
authUser?: any
|
||||
error?: string
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from "./service"
|
||||
export * from "./common"
|
||||
export * from "./provider"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IModuleService } from "../modules-sdk"
|
||||
import {
|
||||
AuthenticationResponse,
|
||||
AuthProviderDTO,
|
||||
AuthUserDTO,
|
||||
CreateAuthProviderDTO,
|
||||
@@ -9,9 +9,10 @@ import {
|
||||
UpdateAuthProviderDTO,
|
||||
UpdateAuthUserDTO,
|
||||
} from "./common"
|
||||
import { FindConfig } from "../common"
|
||||
|
||||
import { Context } from "../shared-context"
|
||||
import { AuthenticationResponse } from "./provider"
|
||||
import { FindConfig } from "../common"
|
||||
import { IModuleService } from "../modules-sdk"
|
||||
|
||||
export interface IAuthenticationModuleService extends IModuleService {
|
||||
authenticate(
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
import { AuthUserDTO } from "./common"
|
||||
import { AuthenticationResponse } from "@medusajs/types";
|
||||
|
||||
export abstract class AbstractAuthenticationModuleProvider {
|
||||
public static PROVIDER: string
|
||||
public static DISPLAY_NAME: string
|
||||
|
||||
public get provider() {
|
||||
return (this.constructor as Function & { PROVIDER: string}).PROVIDER
|
||||
return (this.constructor as Function & { PROVIDER: string }).PROVIDER
|
||||
}
|
||||
|
||||
public get displayName() {
|
||||
return (this.constructor as Function & { DISPLAY_NAME: string}).DISPLAY_NAME
|
||||
return (this.constructor as Function & { DISPLAY_NAME: string })
|
||||
.DISPLAY_NAME
|
||||
}
|
||||
|
||||
abstract authenticate(
|
||||
data: Record<string, unknown>
|
||||
): Promise<AuthenticationResponse>
|
||||
}
|
||||
|
||||
export type AuthenticationResponse = {
|
||||
success: boolean
|
||||
authUser?: AuthUserDTO
|
||||
error?: string
|
||||
}
|
||||
1
packages/utils/src/authentication/index.ts
Normal file
1
packages/utils/src/authentication/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./abstract-authentication-provider"
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./authentication"
|
||||
export * from "./bundles"
|
||||
export * from "./common"
|
||||
export * from "./dal"
|
||||
|
||||
92
yarn.lock
92
yarn.lock
@@ -6060,14 +6060,44 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/hoek@npm:^9.0.0":
|
||||
"@hapi/boom@npm:^10.0.1":
|
||||
version: 10.0.1
|
||||
resolution: "@hapi/boom@npm:10.0.1"
|
||||
dependencies:
|
||||
"@hapi/hoek": ^11.0.2
|
||||
checksum: e4ae8a69bb67c5687320d320a0706ac66e797a659c19fb1c9b909eaefe3b41780e4ecd4382de1297b10c33e9db81f79667324576b9153f57b0cf701293b908d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/bourne@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@hapi/bourne@npm:3.0.0"
|
||||
checksum: 2e2df62f6bc6f32b980ba5bbdc09200c93c55c8306399ec0f2781da088a82aab699498c89fe94fec4acf770210f9aee28c75bfc2f04044849ac01b034134e717
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/hoek@npm:^10.0.1":
|
||||
version: 10.0.1
|
||||
resolution: "@hapi/hoek@npm:10.0.1"
|
||||
checksum: 320d5dc7a4070fa29e6344a3af9e44854980c6606848f7b7f59715174880cc09a1fe1e8adf44cf887100bd8d6a8664e9dc415986b30dc91df13455f7114de549
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/hoek@npm:^11.0.2":
|
||||
version: 11.0.4
|
||||
resolution: "@hapi/hoek@npm:11.0.4"
|
||||
checksum: 3c0e487824daaf3af4c29e46fd57b0c5801ce9164fef2417c70e271cd970e13cc542b196f70ba1cfc9ef944eed825fcac261085ab5e2928c6017428bf576b363
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0":
|
||||
version: 9.3.0
|
||||
resolution: "@hapi/hoek@npm:9.3.0"
|
||||
checksum: a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/topo@npm:^5.0.0":
|
||||
"@hapi/topo@npm:^5.0.0, @hapi/topo@npm:^5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "@hapi/topo@npm:5.1.0"
|
||||
dependencies:
|
||||
@@ -6076,6 +6106,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hapi/wreck@npm:^18.0.0":
|
||||
version: 18.0.1
|
||||
resolution: "@hapi/wreck@npm:18.0.1"
|
||||
dependencies:
|
||||
"@hapi/boom": ^10.0.1
|
||||
"@hapi/bourne": ^3.0.0
|
||||
"@hapi/hoek": ^11.0.2
|
||||
checksum: 46b1b1f750a66c4724964eb6d9192d1d19cfa45e602386aae76f52e3b423c9ae14a03a0f0e9f962e7d973708e1b0b6ab42d2ae77539a691fa77a18c78ccf285c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@headlessui/react@npm:^1.7.18":
|
||||
version: 1.7.18
|
||||
resolution: "@headlessui/react@npm:1.7.18"
|
||||
@@ -7854,10 +7895,12 @@ __metadata:
|
||||
cross-env: ^5.2.1
|
||||
dotenv: ^16.1.4
|
||||
jest: ^29.6.3
|
||||
jsonwebtoken: ^9.0.2
|
||||
knex: 2.4.2
|
||||
medusa-test-utils: ^1.1.40
|
||||
rimraf: ^3.0.2
|
||||
scrypt-kdf: ^2.0.1
|
||||
simple-oauth2: ^5.0.0
|
||||
ts-jest: ^29.1.1
|
||||
ts-node: ^10.9.1
|
||||
tsc-alias: ^1.8.6
|
||||
@@ -12192,7 +12235,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sideway/address@npm:^4.1.3":
|
||||
"@sideway/address@npm:^4.1.3, @sideway/address@npm:^4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@sideway/address@npm:4.1.4"
|
||||
dependencies:
|
||||
@@ -35009,6 +35052,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"joi@npm:^17.6.4":
|
||||
version: 17.12.0
|
||||
resolution: "joi@npm:17.12.0"
|
||||
dependencies:
|
||||
"@hapi/hoek": ^9.3.0
|
||||
"@hapi/topo": ^5.1.0
|
||||
"@sideway/address": ^4.1.4
|
||||
"@sideway/formula": ^3.0.1
|
||||
"@sideway/pinpoint": ^2.0.0
|
||||
checksum: 2378f4ec8de2bc12674ce3e6faac509f52ff4f734c67bf68c288816b20336d4e59433ea1c1e187f1009075c81ec5fa8b5061094feb37a855d6e3ee0cfcd79dd8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"join-component@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "join-component@npm:1.1.0"
|
||||
@@ -35478,6 +35534,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsonwebtoken@npm:^9.0.2":
|
||||
version: 9.0.2
|
||||
resolution: "jsonwebtoken@npm:9.0.2"
|
||||
dependencies:
|
||||
jws: ^3.2.2
|
||||
lodash.includes: ^4.3.0
|
||||
lodash.isboolean: ^3.0.3
|
||||
lodash.isinteger: ^4.0.4
|
||||
lodash.isnumber: ^3.0.3
|
||||
lodash.isplainobject: ^4.0.6
|
||||
lodash.isstring: ^4.0.1
|
||||
lodash.once: ^4.0.0
|
||||
ms: ^2.1.1
|
||||
semver: ^7.5.4
|
||||
checksum: d287a29814895e866db2e5a0209ce730cbc158441a0e5a70d5e940eb0d28ab7498c6bf45029cc8b479639bca94056e9a7f254e2cdb92a2f5750c7f358657a131
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsprim@npm:^1.2.2":
|
||||
version: 1.4.2
|
||||
resolution: "jsprim@npm:1.4.2"
|
||||
@@ -46081,6 +46155,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-oauth2@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "simple-oauth2@npm:5.0.0"
|
||||
dependencies:
|
||||
"@hapi/hoek": ^10.0.1
|
||||
"@hapi/wreck": ^18.0.0
|
||||
debug: ^4.3.4
|
||||
joi: ^17.6.4
|
||||
checksum: 1cb5a4eb9022f656e1bb9a1f43d771dd058d4a4fa181b42d0e1e7ca7b5cfc42e35fad1c722be9bb6fa218398b3b0499010554a7367d2bd85eb9d7634f92546c1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-string-table@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "simple-string-table@npm:1.0.0"
|
||||
|
||||
Reference in New Issue
Block a user