-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(auth): add account service and store
- Loading branch information
1 parent
b987c38
commit 84a3687
Showing
12 changed files
with
304 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { | ||
ChangePassword, GetCustomer, | ||
Login, | ||
Register, | ||
ResetPassword, | ||
} from '../../types/cleeng'; | ||
|
||
import { post, put, patch, get } from './cleeng.service'; | ||
|
||
export const login: Login = async (payload, sandbox) => { | ||
return post(sandbox, '/auths', JSON.stringify(payload)); | ||
}; | ||
|
||
export const register: Register = async (payload, sandbox) => { | ||
return post(sandbox, '/auths', JSON.stringify(payload)); | ||
}; | ||
|
||
export const resetPassword: ResetPassword = async (payload, sandbox) => { | ||
return put(sandbox, '/customers/passwords', JSON.stringify(payload)); | ||
}; | ||
|
||
export const changePassword: ChangePassword = async (payload, sandbox) => { | ||
return patch(sandbox, '/customers/passwords', JSON.stringify(payload)); | ||
}; | ||
|
||
export const getCustomer: GetCustomer = async (payload, sandbox, jwt) => { | ||
return get(sandbox, `/customers/${payload.customerId}`, jwt); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
export const getBaseUrl = (sandbox: boolean) => (sandbox ? 'https://mediastore-sandbox.cleeng.com' : 'https://mediastore.cleeng.com'); | ||
|
||
export const performRequest = async (sandbox: boolean, path: string = '/', method = 'GET', body?: string, jwt?: string) => { | ||
try { | ||
const resp = await fetch(`${getBaseUrl(sandbox)}${path}`, { | ||
headers: { | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json', | ||
Authorization: jwt ? `Bearer ${jwt}` : '', | ||
}, | ||
method, | ||
body, | ||
}); | ||
|
||
return await resp.json(); | ||
} catch (error: unknown) { | ||
return error; | ||
} | ||
}; | ||
|
||
export const get = (sandbox: boolean, path: string, jwt?: string) => performRequest(sandbox, path, 'GET', undefined, jwt); | ||
export const patch = (sandbox: boolean, path: string, body?: string, jwt?: string) => performRequest(sandbox, path, 'PATCH', body, jwt); | ||
export const put = (sandbox: boolean, path: string, body?: string, jwt?: string) => performRequest(sandbox, path, 'PUT', body, jwt); | ||
export const post = (sandbox: boolean, path: string, body?: string, jwt?: string) => performRequest(sandbox, path, 'POST', body, jwt); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { Store } from 'pullstate' | ||
import jwtDecode from 'jwt-decode'; | ||
|
||
import * as accountService from '../services/account.service'; | ||
import type { AuthData, Customer, JwtDetails } from '../../types/cleeng'; | ||
|
||
import { ConfigStore } from './ConfigStore'; | ||
|
||
type AccountStore = { | ||
auth: AuthData | null, | ||
user: Customer | null, | ||
}; | ||
|
||
export const AccountStore = new Store<AccountStore>({ | ||
auth: null, | ||
user: null, | ||
}); | ||
|
||
const afterLogin = async (sandbox: boolean, auth: AuthData) => { | ||
const decodedToken: JwtDetails = jwtDecode(auth.jwt); | ||
const customerId = decodedToken.customerId.toString(); | ||
|
||
const response = await accountService.getCustomer({ customerId }, sandbox, auth.jwt); | ||
|
||
if (response.errors.length) throw new Error(response.errors[0]); | ||
|
||
AccountStore.update(s => { | ||
s.auth = auth; | ||
s.user = response.responseData; | ||
}); | ||
}; | ||
|
||
export const login = async (email: string, password: string) => { | ||
const { config: { cleengId, cleengSandbox } } = ConfigStore.getRawState(); | ||
|
||
if (!cleengId) throw new Error('cleengId is not configured'); | ||
|
||
const response = await accountService.login({ email, password, publisherId: cleengId }, cleengSandbox); | ||
|
||
if (response.errors.length > 0) throw new Error(response.errors[0]); | ||
|
||
return afterLogin(cleengSandbox, response.responseData); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
export type AuthData = { | ||
jwt: string; | ||
customerToken: string; | ||
}; | ||
|
||
export type JwtDetails = { | ||
customerId: number; | ||
exp: number; | ||
publisherId: number; | ||
}; | ||
|
||
export type LoginPayload = { | ||
email: string; | ||
password: string; | ||
offerId?: string; | ||
publisherId?: string; | ||
}; | ||
|
||
export type RegisterPayload = { | ||
email: string; | ||
password: string; | ||
offerId?: string; | ||
publisherId?: string; | ||
locale: string; | ||
country: string; | ||
currency: string; | ||
firstName?: string; | ||
lastName?: string; | ||
externalId?: string; | ||
externalData?: string; | ||
}; | ||
|
||
export type ResetPasswordPayload = { | ||
customerEmail: string; | ||
offerId?: string; | ||
publisherId?: string; | ||
resetUrl?: string; | ||
}; | ||
|
||
export type ChangePasswordPayload = { | ||
customerEmail: string; | ||
publisherId: string; | ||
resetPasswordToken: string; | ||
newPassword: string; | ||
}; | ||
|
||
export type GetCustomerPayload = { | ||
customerId: string; | ||
}; | ||
|
||
export type Subscription = { | ||
subscriptionId: number, | ||
offerId: string, | ||
status: 'active' | 'cancelled' | 'expired' | 'terminated', | ||
expiresAt: number, | ||
nextPaymentPrice: number, | ||
nextPaymentCurrency: string, | ||
paymentGateway: string, | ||
paymentMethod: string, | ||
offerTitle: string, | ||
period: string, | ||
totalPrice: number, | ||
} | ||
|
||
export type Customer = { | ||
id: string; | ||
email: string; | ||
locale: string; | ||
country: string; | ||
currency: string; | ||
lastUserIp: string; | ||
firstName?: string; | ||
lastName?: string; | ||
externalId?: string; | ||
externalData?: string; | ||
}; | ||
|
||
export type Offer = { | ||
offerId: string; | ||
offerPrice: number; | ||
offerCurrency: string; | ||
offerCurrencySymbol: string; | ||
offerCountry: string; | ||
customerPriceInclTax: number; | ||
customerPriceExclTax: number; | ||
customerCurrency: string; | ||
customerCurrencySymbol: string; | ||
customerCountry: string; | ||
discountedCustomerPriceInclTax: number | null; | ||
discountedCustomerPriceExclTax: number | null; | ||
discountPeriods: number | null; | ||
offerUrl: string; | ||
offerTitle: string; | ||
offerDescription: null; | ||
active: boolean; | ||
createdAt: number; | ||
updatedAt: number; | ||
applicableTaxRate: number; | ||
geoRestrictionEnabled: boolean; | ||
geoRestrictionType: string | null; | ||
geoRestrictionCountries: string[]; | ||
socialCommissionRate: number; | ||
averageRating: number; | ||
contentType: string | null; | ||
period: string; | ||
freePeriods: number; | ||
freeDays: number; | ||
expiresAt: string | null; | ||
accessToTags: string[]; | ||
videoId: string | null; | ||
contentExternalId: string | null; | ||
contentExternalData: string | null; | ||
contentAgeRestriction: string | null | ||
} | ||
|
||
export type Order = { | ||
id: number; | ||
customerId: number; | ||
customer: { | ||
locale: string; | ||
email: string | ||
}; | ||
publisherId: number; | ||
offerId: string; | ||
offer: Offer; | ||
totalPrice: number; | ||
priceBreakdown: { | ||
offerPrice: number; | ||
discountAmount: number; | ||
discountedPrice: number; | ||
taxValue: number; | ||
customerServiceFee: number; | ||
paymentMethodFee: number | ||
}; | ||
taxRate: number; | ||
taxBreakdown: string | null; | ||
currency: string; | ||
country: string | null; | ||
paymentMethodId: number; | ||
expirationDate: number; | ||
billingAddress: null; | ||
couponId: null; | ||
discount: { | ||
applied: boolean; | ||
type: string; | ||
periods: string | ||
}; | ||
requiredPaymentDetails: boolean | ||
}; | ||
|
||
export type Payment = { | ||
id: number, | ||
orderId: number, | ||
status: string, | ||
totalAmount: number, | ||
currency: string, | ||
customerId: number, | ||
paymentGateway: string, | ||
paymentMethod: string, | ||
externalPaymentId: string|number, | ||
couponId: number | null, | ||
amount: number, | ||
country: string, | ||
offerType: "subscription", | ||
taxValue: number, | ||
paymentMethodFee: number, | ||
customerServiceFee: number, | ||
rejectedReason: string | null, | ||
refundedReason: string | null, | ||
paymentDetailsId: number | null, | ||
paymentOperation: string | ||
}; | ||
|
||
type CleengResponse<R> = { errors: [string], responseData: R }; | ||
type CleengRequest<P, R> = (payload: P, sandbox: boolean) => Promise<CleengResponse<R>>; | ||
type CleengAuthRequest<P, R> = (payload: P, sandbox: boolean, jwt: string) => Promise<CleengResponse<R>>; | ||
|
||
type Login = CleengRequest<LoginPayload, AuthData>; | ||
type Register = CleengRequest<RegisterPayload, AuthData>; | ||
type ResetPassword = CleengRequest<ResetPasswordPayload, Record<string, unknown>>; | ||
type ChangePassword = CleengRequest<ChangePasswordPayload, Record<string, unknown>>; | ||
type GetCustomer = CleengAuthRequest<GetCustomerPayload, Customer>; |
Oops, something went wrong.