Skip to content

Commit

Permalink
feat: tma customer workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
nxmad committed Nov 17, 2024
1 parent 03ee536 commit 18f0737
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './modules/tma-auth';
export * from './workflows/tma-auth';
export * from './workflows/tma-auth/types';
70 changes: 70 additions & 0 deletions src/workflows/tma-auth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
when,
transform,
createWorkflow,
WorkflowResponse,
type WorkflowData,
} from '@medusajs/framework/workflows-sdk';

// @ts-expect-error: types don't care about this
import type { InitData } from '@telegram-apps/init-data-node';

import type { TmaCustomerWorkflowInput } from './types';
import type { CreateCustomerDTO } from '@medusajs/framework/types';
import { upsertAuthIdentityStep } from './steps/upsert-auth-identity';
import { createCustomersWorkflow, setAuthAppMetadataStep } from '@medusajs/medusa/core-flows';
import { generateJwtTokenForAuthIdentity } from '@medusajs/medusa/api/auth/utils/generate-jwt-token';

export const tmaCustomerWorkflow = createWorkflow('tma-customer', (input: WorkflowData<TmaCustomerWorkflowInput>) => {
const authIdentity = upsertAuthIdentityStep(input);

// Prepare input
const createCustomerInput = transform({ input, authIdentity }, ({ input, authIdentity }): CreateCustomerDTO[] => {
const providerIdentity = authIdentity.provider_identities?.find((p) => p.provider === input.providerId);

const metadata = providerIdentity?.user_metadata as unknown as InitData['user'];

return [
{
last_name: metadata.lastName,
first_name: metadata.firstName,
},
];
});

// When no actor is linked to the auth identity, create a customer
const created = when(authIdentity, (i) => !i.app_metadata).then(() =>
createCustomersWorkflow.runAsStep({
input: {
customersData: createCustomerInput,
},
}),
);

// Prepare input to link the customer to the auth identity
const authMetadataInput = transform({ created, authIdentity }, ({ created, authIdentity }) =>
created
? {
value: created[0].id,
actorType: 'customer',
authIdentityId: authIdentity.id,
}
: null,
);

when(created, (c) => !!c).then(() => setAuthAppMetadataStep(authMetadataInput));

const token = transform({ input, authIdentity }, ({ input, authIdentity }) =>
generateJwtTokenForAuthIdentity(
{
authIdentity,
actorType: 'customer',
},
input.jwtOptions,
),
);

return new WorkflowResponse({
token,
});
});
36 changes: 36 additions & 0 deletions src/workflows/tma-auth/steps/upsert-auth-identity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { TmaCustomerWorkflowInput } from '../types';
import { MedusaError, Modules } from '@medusajs/framework/utils';
import { createStep, StepResponse } from '@medusajs/framework/workflows-sdk';

export const upsertAuthIdentityStep = createStep(
'upsert-auth-identity',
async (input: TmaCustomerWorkflowInput, { container }) => {
const service = container.resolve(Modules.AUTH);
const payload = {
body: {
initDataRaw: input.initRawData,
},
};

const exists = await service.authenticate(input.providerId, payload);

if (exists.success) {
return new StepResponse(exists.authIdentity, null);
}

const created = await service.register(input.providerId, payload);

if (!created.success) {
throw new MedusaError(MedusaError.Types.UNAUTHORIZED, created.error);
}

return new StepResponse(created.authIdentity, created.authIdentity.id);
},
async (createdAuthIdentityId, { container }) => {
const service = container.resolve(Modules.AUTH);

if (createdAuthIdentityId) {
await service.deleteAuthIdentities([createdAuthIdentityId]);
}
},
);
8 changes: 8 additions & 0 deletions src/workflows/tma-auth/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type TmaCustomerWorkflowInput = {
initRawData: string;
providerId: string;
jwtOptions: {
secret: string;
expiresIn: string;
};
};

0 comments on commit 18f0737

Please sign in to comment.