@earnaha/auth0-action-helper
Version:
AHA auth0 action helper
814 lines (786 loc) • 28.1 kB
JavaScript
/* eslint-disable max-len */
const {
describe,
beforeEach,
beforeAll,
afterEach,
expect,
it,
jest,
} = require('@jest/globals');
const axios = require('axios');
const AxiosMockAdapter = require('axios-mock-adapter');
const PostLoginHelper = require('../post.login.js');
describe('PostLoginHelper : Claim Account Flow', () => {
const nowTime = new Date('2024-04-26T07:58:34.861Z');
const envConfig = {
ENV: 'local',
SERVICE: 'aha-local',
DOMAIN: 'https://1f53-2401-e180-8814-4076-522b-1a24-60e4-9edd.ngrok-free.app',
ACCESS_KEY: 'oJucsRNjCnczrAVsIUZxXNYSh',
ACCESS_SALT: '4479748907',
AUTH0_DOMAIN: 'https://aha-local.jp.auth0.com',
AUTH0_CLIENT_ID: 'rR5hZwRTU5PeTQ9iCVtsNrLYS45PaeMY',
AUTH0_CLIENT_SECRET:
'kJR-aAjiUWwcaF-f9JfVaiaePNLnxNL60R2plM2cljPDlmzIGBsv_JYhLRsaJlh0',
SENTRY_DSN: '',
SENTRY_TRACES_SAMPLE_RATE: '0.1',
SENTRY_LOGGER_LEVEL: 'debug',
LINK_ACCOUNT_TIME: '2022-04-22',
OPEN_SEARCH_NODE:
'https://logger:wkb.xdg2ugx3dew!RZV@search-earnaha-log-p5zmiz3blqoub4f43lr4a34wwe.ap-northeast-1.es.amazonaws.com',
};
const inviter = {
userId: '23f253bf-2524-498f-9aa0-a9e594793942',
memberId: '86118a6a-14cc-411f-8b85-e02aebad2ece',
auth0Id: 'auth0|644555911e7caefb9e7739d3',
nickname: 'jessie.kao',
};
const members = {
inviter: {
id: inviter.memberId,
auth0Id: inviter.auth0Id,
email: 'jessie.kao@avancevl.com',
nickname: inviter.nickname,
name: 'jessie.kao',
picture: null,
loginsCount: 3,
lastIp: null,
emailVerified: true,
appMetadata: null,
userMetadata: null,
roles: [],
identities: null,
language: null,
geoip: null,
lastLoginAt: '2023-02-04T10:34:02.968Z',
lastPasswordResetAt: null,
createdAt: '2023-01-24T09:40:08.315Z',
updatedAt: '2023-02-04T10:34:02.968Z',
},
guest: {
id: '76f8f2aa-f751-4f59-bdfe-6e339a7435b7',
auth0Id: 'guest|1714118314859',
email: 'localtest0426a.24nh1i0wz@mail.earnaha.com',
nickname: 'localtest0426a.24nh1i0wz',
name: 'LocalTest0426a',
picture:
'https://www.gravatar.com/avatar/0ce9da9716a240c67c302d7f6a174fcf?d=https%3A%2F%2Fui-avatars.com%2Fapi%2Flocaltest0426a.24nh1i0wz%2F240%2Fe74c3c%2Ffff%2F2%2F0.5%2Ffalse%2Ftrue%2Fsvg',
loginsCount: 0,
lastIp: null,
emailVerified: false,
scope: null,
appMetadata: 'null',
userMetadata: JSON.stringify(inviter),
roles: 'guest',
identities: 'null',
language: null,
geoip: null,
lastLoginAt: '2024-04-26T07:58:34.859Z',
lastPasswordResetAt: null,
createdAt: '2024-04-26T07:58:34.861Z',
updatedAt: '2024-04-26T07:58:34.861Z,',
reservedEmail: null,
claimedAt: null,
},
};
const users = {
namePwdAuth: {
created_at: '2024-04-26T07:56:15.927Z',
email: 'jessie.kao+2024042610@avancevl.com',
email_verified: false,
identities: [
{
connection: 'Username-Password-Authentication',
provider: 'auth0',
user_id: '662b5e1f9236b6da6d2fda79',
isSocial: false,
},
],
name: members.guest.name,
nickname: members.guest.nickname,
picture:
'https://s.gravatar.com/avatar/55a1b5db679fa9673a4ef5406434acb8?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fje.png',
updated_at: '2024-04-26T07:56:31.066Z',
user_id: 'auth0|662b5e1f9236b6da6d2fda79',
user_metadata: {
claimUsername: members.guest.nickname,
inviter,
memberId: members.guest.id,
},
last_ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
last_login: '2024-04-26T07:56:15.919Z',
logins_count: 1,
blocked_for: [],
guardian_authenticators: [],
passkeys: [],
},
thirdPartyAuth: {
created_at: '2024-04-26T08:02:20.220Z',
email: 'jessie.tzu.chi.kao@gmail.com',
email_verified: true,
family_name: 'Kao',
given_name: 'Tzuchi',
identities: [
{
provider: 'google-oauth2',
user_id: '105069091609398204388',
connection: 'google-oauth2',
isSocial: true,
},
],
name: 'Tzuchi Kao',
nickname: 'jessie.tzu.chi.kao',
picture:
'https://lh3.googleusercontent.com/a/ACg8ocI6Ggok8gtk7gbYpInb4POcUy01bEGC0-F8e1iBFZ2n2VxbcOw=s96-c',
updated_at: '2024-04-26T08:02:27.981Z',
user_id: 'google-oauth2|105069091609398204388',
user_metadata: {
claimUsername: members.guest.nickname,
inviter,
memberId: members.guest.id,
},
last_ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
last_login: '2024-04-26T08:02:20.214Z',
logins_count: 1,
blocked_for: [],
guardian_authenticators: [],
passkeys: [],
},
inviter: {
created_at: '2023-04-23T15:58:09.339Z',
email: 'jessie.kao@avancevl.com',
email_verified: true,
identities: [
{
connection: 'Username-Password-Authentication',
provider: 'auth0',
user_id: '644555911e7caefb9e7739d3',
isSocial: false,
},
{
profileData: {
email: 'jessie.kao@avancevl.com',
email_verified: true,
name: 'Jessie Kao',
given_name: 'Jessie',
family_name: 'Kao',
picture:
'https://lh3.googleusercontent.com/a/ACg8ocL6dBNGx2hZkUaxDQaP8zkoollppAtsg-CCQzdzeKpi3bk=s96-c',
locale: 'en',
idp_tenant_domain: 'avancevl.com',
},
provider: 'google-oauth2',
user_id: '115854337626315705505',
connection: 'google-oauth2',
isSocial: true,
},
],
name: 'user169',
nickname: 'user169',
picture:
'https://s.gravatar.com/avatar/965cff0a62d902bac8d04efd4a31341c?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fus.png',
updated_at: '2024-04-26T08:00:14.874Z',
user_id: 'auth0|644555911e7caefb9e7739d3',
user_metadata: {
hasBeenInvited: true,
memberId: '86118a6a-14cc-411f-8b85-e02aebad2ece',
extendTrialByRef3Friends: true,
invitedMemberIds: [members.guest.id],
totalExtendedTimes: 1,
referredPhones: ['+886987654321'],
googleOneTap: {
aud: '55252414634-3bnaeeb0pk3du8e6cqi447ak4l2o05ao.apps.googleusercontent.com',
azp: '55252414634-3bnaeeb0pk3du8e6cqi447ak4l2o05ao.apps.googleusercontent.com',
iss: 'https://accounts.google.com',
nbf: 1710148478,
sub: '115854337626315705505',
},
country: 'TW',
timezone: 'Asia/Taipei',
trialExtendLogs: [
{
accepter: members.guest.id,
membershipId: '626ee05f-8bf6-44ed-9057-6fb4ef9000a0',
tierFrom: 1,
tierTo: 1,
periodFrom: 5,
periodTo: 5,
expiredAtFrom: 1717997451720,
expiredAtTo: 1718429451720,
timeDiffMs: 432000000,
},
],
},
last_password_reset: '2023-04-23T16:00:11.078Z',
last_ip: '150.116.99.86',
last_login: '2024-03-20T15:17:58.853Z',
logins_count: 58,
blocked_for: [],
guardian_authenticators: [],
passkeys: [],
},
};
// https://auth0.com/docs/customize/actions/flows-and-triggers/login-flow/event-object
const auth0ActionEvent = {
namePwdAuth: {
transaction: {
acr_values: [],
id: 'HuRqxuj8WNrQz0GioY2MF6pDA95vzYKF',
linking_id: null,
locale: 'en',
login_hint: null,
prompt: [],
protocol: 'oidc-basic-profile',
redirect_uri: 'http://localhost:3000/api/auth/callback',
requested_scopes: ['openid', 'email', 'profile'],
response_mode: null,
response_type: ['code'],
state: 'eyJyZXR1cm5UbyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC8ifQ',
ui_locales: [],
},
authentication: { methods: [{}] },
authorization: { roles: [] },
connection: {
id: 'con_86C3Ae0EGriXeOyV',
metadata: {},
name: 'Username-Password-Authentication',
strategy: 'auth0',
},
organization: undefined,
resource_server: {
identifier: 'https://aha-local.jp.auth0.com/userinfo',
},
tenant: { id: envConfig.SERVICE },
secrets: envConfig,
session: {
device: {
initial_asn: '24157',
initial_ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
},
id: 'e5cWzQ_0I1Kv9tLa2xR44eK8PvDhkuQ3',
},
configuration: {},
client: {
client_id: envConfig.AUTH0_CLIENT_ID,
name: envConfig.SERVICE,
metadata: {},
},
request: {
ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
asn: '24157',
method: 'GET',
query: {
claimUsername: members.guest.nickname,
client_id: 'rR5hZwRTU5PeTQ9iCVtsNrLYS45PaeMY',
code_challenge:
'AIOnXFQejU8n28ijONIsTFmCL6tseO2muVJ7rpZiTKw',
code_challenge_method: 'S256',
country: '',
nonce: 'MR-SnIHj204SzZZLArap2KDC15QfgfR9HT8F3P-aJOQ',
protocol: 'oauth2',
redirect_uri: 'http://localhost:3000/api/auth/callback',
response_type: 'code',
scope: 'openid email profile',
screen_hint: 'signup',
state: 'eyJyZXR1cm5UbyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC8ifQ',
timezone: '',
},
body: {},
geoip: {
cityName: 'Banqiao',
continentCode: 'AS',
countryCode3: 'TWN',
countryCode: 'TW',
countryName: 'Taiwan',
latitude: 25.0104,
longitude: 121.4684,
subdivisionCode: 'NWT',
subdivisionName: 'New Taipei',
timeZone: 'Asia/Taipei',
},
hostname: 'aha-local.jp.auth0.com',
language: undefined,
user_agent:
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
},
stats: { logins_count: 1 },
user: {
app_metadata: users.namePwdAuth.app_metadata,
created_at: users.namePwdAuth.created_at,
email_verified: users.namePwdAuth.email_verified,
email: users.namePwdAuth.email,
family_name: undefined,
given_name: undefined,
identities: users.namePwdAuth.identities,
last_password_reset: undefined,
name: users.namePwdAuth.email, // default name in event is email
nickname: users.namePwdAuth.email, // default name in event is email
phone_number: undefined,
phone_verified: undefined,
picture: users.namePwdAuth.picture,
updated_at: users.namePwdAuth.updated_at,
user_id: users.namePwdAuth.user_id,
user_metadata: {}, // users.namePwdAuth.user_metadata,
username: undefined,
multifactor: users.namePwdAuth.multifactor,
enrolledFactors: undefined,
},
},
thirdPartyAuth: {
transaction: {
acr_values: [],
id: 'mNlKVeahaDUedCC9Y1ASde-VuQVzcXbD',
linking_id: null,
locale: 'en',
login_hint: null,
prompt: [],
protocol: 'oidc-basic-profile',
redirect_uri: 'http://localhost:3000/api/auth/callback',
requested_scopes: ['openid', 'email', 'profile'],
response_mode: null,
response_type: ['code'],
state: 'eyJyZXR1cm5UbyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC8ifQ',
ui_locales: [],
},
authentication: { methods: [{}] },
authorization: { roles: [] },
connection: {
id: 'con_w9HTFNr7g0AQnnuc',
metadata: {},
name: 'google-oauth2',
strategy: 'google-oauth2',
},
organization: undefined,
resource_server: {
identifier: 'https://aha-local.jp.auth0.com/userinfo',
},
tenant: { id: envConfig.SERVICE },
secrets: envConfig,
session: {
device: {
initial_asn: '24157',
initial_ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
},
id: 'yfrMmACmB0vYwXGfVAv_FFT-EN2CDsHu',
},
configuration: {},
client: {
client_id: envConfig.AUTH0_CLIENT_ID,
name: envConfig.SERVICE,
metadata: {},
},
request: {
ip: '2403:c300:4553:52bd:6a7d:cbb7:52b0:6795',
asn: '24157',
method: 'GET',
query: {
claimUsername: members.guest.nickname,
client_id: 'rR5hZwRTU5PeTQ9iCVtsNrLYS45PaeMY',
code_challenge:
'klaqLN_vuB3mCuq_Gajk3mrxykvoQMgPPFWi8Y2QEzk',
code_challenge_method: 'S256',
country: '',
nonce: 'tI89d-svCkGosl18KSdPf5zg_XMf56zbKrVcucJIum8',
protocol: 'oauth2',
redirect_uri: 'http://localhost:3000/api/auth/callback',
response_type: 'code',
scope: 'openid email profile',
screen_hint: 'signup',
state: 'eyJyZXR1cm5UbyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC8ifQ',
timezone: '',
},
body: {},
geoip: {
cityName: 'Banqiao',
continentCode: 'AS',
countryCode3: 'TWN',
countryCode: 'TW',
countryName: 'Taiwan',
latitude: 25.0104,
longitude: 121.4684,
subdivisionCode: 'NWT',
subdivisionName: 'New Taipei',
timeZone: 'Asia/Taipei',
},
hostname: 'aha-local.jp.auth0.com',
language: undefined,
user_agent:
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
},
stats: { logins_count: 1 },
user: {
app_metadata: users.thirdPartyAuth.app_metadata,
created_at: users.thirdPartyAuth.created_at,
email_verified: users.thirdPartyAuth.email_verified,
email: users.thirdPartyAuth.email,
family_name: users.thirdPartyAuth.family_name,
given_name: users.thirdPartyAuth.given_name,
identities: users.thirdPartyAuth.identities,
last_password_reset: undefined,
name: users.thirdPartyAuth.name,
nickname: users.thirdPartyAuth.nickname,
phone_number: undefined,
phone_verified: undefined,
picture: users.thirdPartyAuth.picture,
updated_at: users.thirdPartyAuth.updated_at,
user_id: users.thirdPartyAuth.user_id,
user_metadata: {}, // users.thirdPartyAuth.user_metadata,
username: undefined,
multifactor: users.thirdPartyAuth.multifactor,
enrolledFactors: undefined,
},
},
};
// https://auth0.com/docs/customize/actions/flows-and-triggers/login-flow/api-object
const auth0ActionApi = {
access: {
deny: jest.fn().mockImplementation((reason, userMessage) => ({
reason,
userMessage,
})),
},
cache: {
get: jest.fn().mockImplementation(key => key),
set: jest.fn().mockImplementation((key, value, options) => ({
key,
value,
options,
})),
delete: jest.fn().mockImplementation(key => key),
},
accessToken: {
setCustomClaim: jest.fn().mockImplementation((name, value) => ({
name,
value,
})),
addScope: jest.fn().mockImplementation(key => key),
removeScope: jest.fn().mockImplementation(key => key),
},
authentication: {
recordMethod: jest
.fn()
.mockImplementation(providerUrl => providerUrl),
challengeWith: jest.fn().mockImplementation((factor, options) => ({
factor,
options,
})),
challengeWithAny: jest.fn().mockImplementation(factors => factors),
enrollWith: jest.fn().mockImplementation((factor, options) => ({
factor,
options,
})),
enrollWithAny: jest.fn().mockImplementation(factors => factors),
setPrimaryUser: jest
.fn()
.mockImplementation(primaryUserId => primaryUserId),
},
idToken: {
setCustomClaim: jest.fn().mockImplementation((name, value) => ({
name,
value,
})),
},
multifactor: {
enable: jest.fn().mockImplementation((provider, options) => ({
provider,
options,
})),
},
user: {
setUserMetadata: jest.fn().mockImplementation((name, value) => ({
name,
value,
})),
setAppMetadata: jest.fn().mockImplementation((name, value) => ({
name,
value,
})),
},
redirect: {
encodeToken: jest.fn().mockImplementation(options => options),
sendUserTo: jest.fn().mockImplementation((url, options) => ({
url,
options,
})),
validateToken: jest.fn().mockImplementation(options => options),
},
rules: {
wasExecuted: jest.fn().mockImplementation(ruleId => ruleId),
},
samlResponse: {
setAttribute: jest.fn().mockImplementation((attribute, value) => ({
attribute,
value,
})),
setAudience: jest.fn().mockImplementation(audience => audience),
setEncryptionPublicKey: jest
.fn()
.mockImplementation(publicKey => publicKey),
setRecipient: jest.fn().mockImplementation(recipient => recipient),
setCreateUpnClaim: jest
.fn()
.mockImplementation(createUpnClaim => createUpnClaim),
setPassthroughClaimsWithNoMapping: jest
.fn()
.mockImplementation(
passthroughClaimsWithNoMapping =>
passthroughClaimsWithNoMapping,
),
setMapUnknownClaimsAsIs: jest
.fn()
.mockImplementation(
mapUnknownClaimsAsIs => mapUnknownClaimsAsIs,
),
setMapIdentities: jest
.fn()
.mockImplementation(mapIdentities => mapIdentities),
setDestination: jest
.fn()
.mockImplementation(destination => destination),
setLifetimeInSeconds: jest
.fn()
.mockImplementation(lifetimeInSeconds => lifetimeInSeconds),
setSignResponse: jest
.fn()
.mockImplementation(signResponse => signResponse),
setNameIdentifierFormat: jest
.fn()
.mockImplementation(
nameIdentifierFormat => nameIdentifierFormat,
),
setNameIdentifierProbes: jest
.fn()
.mockImplementation(
nameIdentifierProbes => nameIdentifierProbes,
),
setAuthnContextClassRef: jest
.fn()
.mockImplementation(
authnContextClassRef => authnContextClassRef,
),
setSigningCert: jest
.fn()
.mockImplementation(signingCert => signingCert),
setIncludeAttributeNameFormat: jest
.fn()
.mockImplementation(
includeAttributeNameFormat => includeAttributeNameFormat,
),
setTypedAttributes: jest
.fn()
.mockImplementation(typedAttributes => typedAttributes),
setEncryptionCert: jest
.fn()
.mockImplementation(encryptionCert => encryptionCert),
setCert: jest.fn().mockImplementation(cert => cert),
setKey: jest.fn().mockImplementation(key => key),
setSignatureAlgorithm: jest
.fn()
.mockImplementation(signatureAlgorithm => signatureAlgorithm),
setDigestAlgorithm: jest
.fn()
.mockImplementation(digestAlgorithm => digestAlgorithm),
},
};
const apiAuthJwtToken = `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTY3NjA4ODM3MSwiZXhwIjoxNjc2MzQ3NTcxLCJhdWQiOiJhaGEtbG9jYWwiLCJzdWIiOiIyM2YyNTNiZi0yNTI0LTQ5OGYtOWFhMC1hOWU1OTQ3OTM5NDIiLCJqdGkiOiI2YjZhZDg2MC1hOWMxLTExZWQtOGIwOC1iM2QwMGQ4N2FkZGEifQ.HFLLjxMEmTi0rqOl0_CqmRPVKvK4tHt30XX4zrYV4wDlAzGsf-Fk40m-qzpo3DTbLU9Ovxz-OR6TRAQZbz2lVMz4kGcG1_pnXHIwRI59nEJn0AO9xRhqDTm9_0scpZt_G119C09RYPBj08HcUP2GVj8lQN-Wovcmq9gKakc_nD0`;
const serverAccessKey =
'b0p1Y3NSTmpDbmN6ckFWc0lVWnhYTllTaCswMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDArYWhhLWxvY2FsKzE3MDAyMDE5NjgwNTg=';
const userInfoEncodedState =
'eyJ1c2VyX2lkIjoiZ29vZ2xlLW9hdXRoMnwxMDUwNjkwOTE2MDkzOTgyMDQzODgiLCJlbWFpbCI6Implc3NpZS50enUuY2hpLmthb0BnbWFpbC5jb20iLCJpZGVudGl0aWVzIjpbeyJwcm92aWRlciI6Imdvb2dsZS1vYXV0aDIiLCJ1c2VyX2lkIjoiMTA1MDY5MDkxNjA5Mzk4MjA0Mzg4IiwiY29ubmVjdGlvbiI6Imdvb2dsZS1vYXV0aDIiLCJpc1NvY2lhbCI6dHJ1ZX1dfQ%3D%3D';
const auth0UserToken = {
data: {
access_token: `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImMyNUVPdVRVNEtvQVZPczJjdXh2MiJ9.eyJpc3MiOiJodHRwczovL2Rldi1vcXd1LmpwLmF1dGgwLmNvbS8iLCJzdWIiOiJzelBBbVNYQmpSN3dIWURGMUhZdm50TUE0R0RyT0pDUkBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9kZXYtb3F3dS5qcC5hdXRoMC5jb20vYXBpL3YyLyIsImlhdCI6MTY3NjA4NzEzMywiZXhwIjoxNjc2MTczNTMzLCJhenAiOiJzelBBbVNYQmpSN3dIWURGMUhZdm50TUE0R0RyT0pDUiIsInNjb3BlIjoicmVhZDpjbGllbnRfZ3JhbnRzIGNyZWF0ZTpjbGllbnRfZ3JhbnRzIGRlbGV0ZTpjbGllbnRfZ3JhbnRzIHVwZGF0ZTpjbGllbnRfZ3JhbnRzIHJlYWQ6dXNlcnMgdXBkYXRlOnVzZXJzIGRlbGV0ZTp1c2VycyBjcmVhdGU6dXNlcnMgcmVhZDp1c2Vyc19hcHBfbWV0YWRhdGEgdXBkYXRlOnVzZXJzX2FwcF9tZXRhZGF0YSBkZWxldGU6dXNlcnNfYXBwX21ldGFkYXRhIGNyZWF0ZTp1c2Vyc19hcHBfbWV0YWRhdGEgcmVhZDp1c2VyX2N1c3RvbV9ibG9ja3MgY3JlYXRlOnVzZXJfY3VzdG9tX2Jsb2NrcyBkZWxldGU6dXNlcl9jdXN0b21fYmxvY2tzIGNyZWF0ZTp1c2VyX3RpY2tldHMgcmVhZDpjbGllbnRzIHVwZGF0ZTpjbGllbnRzIGRlbGV0ZTpjbGllbnRzIGNyZWF0ZTpjbGllbnRzIHJlYWQ6Y2xpZW50X2tleXMgdXBkYXRlOmNsaWVudF9rZXlzIGRlbGV0ZTpjbGllbnRfa2V5cyBjcmVhdGU6Y2xpZW50X2tleXMgcmVhZDpjb25uZWN0aW9ucyB1cGRhdGU6Y29ubmVjdGlvbnMgZGVsZXRlOmNvbm5lY3Rpb25zIGNyZWF0ZTpjb25uZWN0aW9ucyByZWFkOnJlc291cmNlX3NlcnZlcnMgdXBkYXRlOnJlc291cmNlX3NlcnZlcnMgZGVsZXRlOnJlc291cmNlX3NlcnZlcnMgY3JlYXRlOnJlc291cmNlX3NlcnZlcnMgcmVhZDpkZXZpY2VfY3JlZGVudGlhbHMgdXBkYXRlOmRldmljZV9jcmVkZW50aWFscyBkZWxldGU6ZGV2aWNlX2NyZWRlbnRpYWxzIGNyZWF0ZTpkZXZpY2VfY3JlZGVudGlhbHMgcmVhZDpydWxlcyB1cGRhdGU6cnVsZXMgZGVsZXRlOnJ1bGVzIGNyZWF0ZTpydWxlcyByZWFkOnJ1bGVzX2NvbmZpZ3MgdXBkYXRlOnJ1bGVzX2NvbmZpZ3MgZGVsZXRlOnJ1bGVzX2NvbmZpZ3MgcmVhZDpob29rcyB1cGRhdGU6aG9va3MgZGVsZXRlOmhvb2tzIGNyZWF0ZTpob29rcyByZWFkOmFjdGlvbnMgdXBkYXRlOmFjdGlvbnMgZGVsZXRlOmFjdGlvbnMgY3JlYXRlOmFjdGlvbnMgcmVhZDplbWFpbF9wcm92aWRlciB1cGRhdGU6ZW1haWxfcHJvdmlkZXIgZGVsZXRlOmVtYWlsX3Byb3ZpZGVyIGNyZWF0ZTplbWFpbF9wcm92aWRlciBibGFja2xpc3Q6dG9rZW5zIHJlYWQ6c3RhdHMgcmVhZDppbnNpZ2h0cyByZWFkOnRlbmFudF9zZXR0aW5ncyB1cGRhdGU6dGVuYW50X3NldHRpbmdzIHJlYWQ6bG9ncyByZWFkOmxvZ3NfdXNlcnMgcmVhZDpzaGllbGRzIGNyZWF0ZTpzaGllbGRzIHVwZGF0ZTpzaGllbGRzIGRlbGV0ZTpzaGllbGRzIHJlYWQ6YW5vbWFseV9ibG9ja3MgZGVsZXRlOmFub21hbHlfYmxvY2tzIHVwZGF0ZTp0cmlnZ2VycyByZWFkOnRyaWdnZXJzIHJlYWQ6Z3JhbnRzIGRlbGV0ZTpncmFudHMgcmVhZDpndWFyZGlhbl9mYWN0b3JzIHVwZGF0ZTpndWFyZGlhbl9mYWN0b3JzIHJlYWQ6Z3VhcmRpYW5fZW5yb2xsbWVudHMgZGVsZXRlOmd1YXJkaWFuX2Vucm9sbG1lbnRzIGNyZWF0ZTpndWFyZGlhbl9lbnJvbGxtZW50X3RpY2tldHMgcmVhZDp1c2VyX2lkcF90b2tlbnMgY3JlYXRlOnBhc3N3b3Jkc19jaGVja2luZ19qb2IgZGVsZXRlOnBhc3N3b3Jkc19jaGVja2luZ19qb2IgcmVhZDpjdXN0b21fZG9tYWlucyBkZWxldGU6Y3VzdG9tX2RvbWFpbnMgY3JlYXRlOmN1c3RvbV9kb21haW5zIHVwZGF0ZTpjdXN0b21fZG9tYWlucyByZWFkOmVtYWlsX3RlbXBsYXRlcyBjcmVhdGU6ZW1haWxfdGVtcGxhdGVzIHVwZGF0ZTplbWFpbF90ZW1wbGF0ZXMgcmVhZDptZmFfcG9saWNpZXMgdXBkYXRlOm1mYV9wb2xpY2llcyByZWFkOnJvbGVzIGNyZWF0ZTpyb2xlcyBkZWxldGU6cm9sZXMgdXBkYXRlOnJvbGVzIHJlYWQ6cHJvbXB0cyB1cGRhdGU6cHJvbXB0cyByZWFkOmJyYW5kaW5nIHVwZGF0ZTpicmFuZGluZyBkZWxldGU6YnJhbmRpbmcgcmVhZDpsb2dfc3RyZWFtcyBjcmVhdGU6bG9nX3N0cmVhbXMgZGVsZXRlOmxvZ19zdHJlYW1zIHVwZGF0ZTpsb2dfc3RyZWFtcyBjcmVhdGU6c2lnbmluZ19rZXlzIHJlYWQ6c2lnbmluZ19rZXlzIHVwZGF0ZTpzaWduaW5nX2tleXMgcmVhZDpsaW1pdHMgdXBkYXRlOmxpbWl0cyBjcmVhdGU6cm9sZV9tZW1iZXJzIHJlYWQ6cm9sZV9tZW1iZXJzIGRlbGV0ZTpyb2xlX21lbWJlcnMgcmVhZDplbnRpdGxlbWVudHMgcmVhZDphdHRhY2tfcHJvdGVjdGlvbiB1cGRhdGU6YXR0YWNrX3Byb3RlY3Rpb24gcmVhZDpvcmdhbml6YXRpb25zIHVwZGF0ZTpvcmdhbml6YXRpb25zIGNyZWF0ZTpvcmdhbml6YXRpb25zIGRlbGV0ZTpvcmdhbml6YXRpb25zIGNyZWF0ZTpvcmdhbml6YXRpb25fbWVtYmVycyByZWFkOm9yZ2FuaXphdGlvbl9tZW1iZXJzIGRlbGV0ZTpvcmdhbml6YXRpb25fbWVtYmVycyBjcmVhdGU6b3JnYW5pemF0aW9uX2Nvbm5lY3Rpb25zIHJlYWQ6b3JnYW5pemF0aW9uX2Nvbm5lY3Rpb25zIHVwZGF0ZTpvcmdhbml6YXRpb25fY29ubmVjdGlvbnMgZGVsZXRlOm9yZ2FuaXphdGlvbl9jb25uZWN0aW9ucyBjcmVhdGU6b3JnYW5pemF0aW9uX21lbWJlcl9yb2xlcyByZWFkOm9yZ2FuaXphdGlvbl9tZW1iZXJfcm9sZXMgZGVsZXRlOm9yZ2FuaXphdGlvbl9tZW1iZXJfcm9sZXMgY3JlYXRlOm9yZ2FuaXphdGlvbl9pbnZpdGF0aW9ucyByZWFkOm9yZ2FuaXphdGlvbl9pbnZpdGF0aW9ucyBkZWxldGU6b3JnYW5pemF0aW9uX2ludml0YXRpb25zIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.rHOgYOAG_HYlrUKey6j9nkKvyKwt8q_rVliqEZSBwoBjZ3CvEMDA1vXLPQLfGUHUw3S3R6SSPUSHIkSKsu2TOmHXVBPiTEd-cCap5_5oGWABrymRTfT4fPO6HyEvgBXAPAnh8tetLYp5jXvsreYt-qafaM7CWpwYryFxKO0-bEyUSEkWIfFdDwheT90QMgrvzve5FMHCMv7nna-DsqlFAYoGLAcqgQaB0wd_Ker7pypNmrzIX08KOggA0We3loPL5p5uiRZiwjT5-HKuFPxDgGqUSU-LNAbgkpUulZ3q95d1oVKEYY-nGAEsagdEAiExrgG9SQ_4dT35vVpUdED3pQ`,
},
};
const claimedGuests = {
namePwdAuth: {
memberLogin: {
memberId: members.guest.id,
accessToken: apiAuthJwtToken,
accessTokenExpiredIn: 259200000,
refreshToken: apiAuthJwtToken,
refreshTokenExpiredIn: 604800000,
},
member: {
...members.guest,
auth0Id: users.namePwdAuth.user_id,
email: users.namePwdAuth.email,
picture: users.namePwdAuth.picture,
loginsCount: auth0ActionEvent.namePwdAuth.stats.logins_count,
lastIp: auth0ActionEvent.namePwdAuth.request.ip,
emailVerified: false,
scope: auth0ActionEvent.namePwdAuth.transaction.requested_scopes.join(
' ',
),
geoip: JSON.stringify(
auth0ActionEvent.namePwdAuth.request.geoip,
),
appMetadata: JSON.stringify(users.namePwdAuth.app_metadata),
userMetadata: JSON.stringify(users.namePwdAuth.user_metadata),
roles: null,
identities: JSON.stringify(users.namePwdAuth.identities),
reservedEmail: members.guest.email,
claimedAt: nowTime,
},
referrer: members.inviter,
removeAuth0UserId: null,
isSignup: true,
},
thirdPartyAuth: {
memberLogin: {
memberId: members.guest.id,
accessToken: apiAuthJwtToken,
accessTokenExpiredIn: 259200000,
refreshToken: apiAuthJwtToken,
refreshTokenExpiredIn: 604800000,
},
member: {
...members.guest,
auth0Id: users.thirdPartyAuth.user_id,
email: users.thirdPartyAuth.email,
picture: users.thirdPartyAuth.picture,
loginsCount: auth0ActionEvent.thirdPartyAuth.stats.logins_count,
lastIp: auth0ActionEvent.thirdPartyAuth.request.ip,
emailVerified: false,
scope: auth0ActionEvent.thirdPartyAuth.transaction.requested_scopes.join(
' ',
),
geoip: JSON.stringify(
auth0ActionEvent.thirdPartyAuth.request.geoip,
),
appMetadata: JSON.stringify(users.thirdPartyAuth.app_metadata),
userMetadata: JSON.stringify(
users.thirdPartyAuth.user_metadata,
),
roles: null,
identities: JSON.stringify(users.thirdPartyAuth.identities),
reservedEmail: members.guest.email,
claimedAt: nowTime,
},
referrer: members.inviter,
removeAuth0UserId: null,
isSignup: true,
},
};
let axiosMockAdapter;
let helper;
beforeAll(async () => {
axiosMockAdapter = new AxiosMockAdapter(axios);
});
beforeEach(async () => {
helper = new PostLoginHelper(envConfig);
helper.getServerAccessKey = jest
.fn()
.mockResolvedValue(serverAccessKey);
axiosMockAdapter
.onPost(`${envConfig.AUTH0_DOMAIN}/oauth/token`)
.reply(200, auth0UserToken.data);
axiosMockAdapter
.onGet(
`${envConfig.DOMAIN}/auth/v3/login/existing-check?state=${userInfoEncodedState}`,
)
.reply(200, {
data: {
id: null,
email: null,
},
});
});
afterEach(() => {
axiosMockAdapter.reset();
jest.restoreAllMocks();
});
it('Claim account by name-password-auth should success', async () => {
axiosMockAdapter
.onGet(
`${
envConfig.AUTH0_DOMAIN
}/api/v2/users-by-email?email=${encodeURIComponent(
users.namePwdAuth.email.toLowerCase(),
)}`,
)
.replyOnce(200, []);
axiosMockAdapter
.onPost(`${envConfig.DOMAIN}/auth/v3/member/guest/claim`)
.replyOnce(200, {
data: claimedGuests.namePwdAuth,
});
axiosMockAdapter
.onPatch(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.namePwdAuth.user_id}`,
)
.replyOnce(args => [
200,
{ ...users.namePwdAuth, ...JSON.parse(args.data) },
]);
axiosMockAdapter
.onGet(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.inviter.user_id}`,
)
.replyOnce(200, users.inviter);
axiosMockAdapter
.onPatch(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.inviter.user_id}`,
)
.replyOnce(args => [
200,
{ ...users.inviter, ...JSON.parse(args.data) },
]);
jest.useFakeTimers().setSystemTime(nowTime);
const res = await helper.exec(
auth0ActionEvent.namePwdAuth,
auth0ActionApi,
);
expect(res.member.memberId).toEqual(members.guest.id);
expect(res.member.auth0Id).toEqual(users.namePwdAuth.user_id);
expect(res.isSignup).toBeTruthy();
jest.useRealTimers();
});
it('Claim account by third-party-auth should success', async () => {
axiosMockAdapter
.onGet(
`${
envConfig.AUTH0_DOMAIN
}/api/v2/users-by-email?email=${encodeURIComponent(
users.thirdPartyAuth.email.toLowerCase(),
)}`,
)
.replyOnce(200, []);
axiosMockAdapter
.onPost(`${envConfig.DOMAIN}/auth/v3/member/guest/claim`)
.replyOnce(200, {
data: claimedGuests.thirdPartyAuth,
});
axiosMockAdapter
.onPatch(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.thirdPartyAuth.user_id}`,
)
.replyOnce(args => [
200,
{ ...users.thirdPartyAuth, ...JSON.parse(args.data) },
]);
axiosMockAdapter
.onGet(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.inviter.user_id}`,
)
.replyOnce(200, users.inviter);
axiosMockAdapter
.onPatch(
`${envConfig.AUTH0_DOMAIN}/api/v2/users/${users.inviter.user_id}`,
)
.replyOnce(args => [
200,
{ ...users.inviter, ...JSON.parse(args.data) },
]);
jest.useFakeTimers().setSystemTime(nowTime);
const res = await helper.exec(
auth0ActionEvent.thirdPartyAuth,
auth0ActionApi,
);
expect(res.member.memberId).toEqual(members.guest.id);
expect(res.member.auth0Id).toEqual(users.thirdPartyAuth.user_id);
expect(res.isSignup).toBeTruthy();
jest.useRealTimers();
});
});