0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

feat(core,schemas): log register (#601)

This commit is contained in:
IceHe.xyz 2022-04-26 11:49:11 +08:00 committed by GitHub
parent 3aa4342f2e
commit a10b427c87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 8 deletions

View file

@ -690,6 +690,7 @@ describe('sessionRoutes', () => {
describe('POST /session/register/social', () => {
it('register with social, assign result and redirect', async () => {
interactionDetails.mockResolvedValueOnce({
jti: 'jti',
result: {
socialUserInfo: { connectorId: 'connectorId', userInfo: { id: 'user1' } },
},
@ -759,6 +760,7 @@ describe('sessionRoutes', () => {
});
it('updates user identities', async () => {
interactionDetails.mockResolvedValueOnce({
jti: 'jti',
result: {
login: { accountId: 'user1' },
socialUserInfo: {

View file

@ -306,7 +306,10 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
}),
}),
async (ctx, next) => {
const { jti } = await provider.interactionDetails(ctx.req, ctx.res);
const { username, password } = ctx.guard.body;
const type = 'RegisterUsernamePassword';
ctx.log(type, { sessionId: jti, username });
assertThat(
password,
@ -324,6 +327,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
);
const id = await generateUserId();
ctx.log(type, { userId: id });
const { passwordEncryptionSalt, passwordEncrypted, passwordEncryptionMethod } =
encryptUserPassword(id, password);
@ -358,6 +363,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
async (ctx, next) => {
const { jti } = await provider.interactionDetails(ctx.req, ctx.res);
const { phone } = ctx.guard.body;
const type = 'RegisterSmsSendPasscode';
ctx.log(type, { sessionId: jti, phone });
assertThat(
!(await hasUserWithPhone(phone)),
@ -365,6 +372,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
);
const passcode = await createPasscode(jti, PasscodeType.Register, { phone });
ctx.log(type, { sessionId: jti, phone, passcode });
await sendPasscode(passcode);
ctx.status = 204;
@ -378,6 +387,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
async (ctx, next) => {
const { jti } = await provider.interactionDetails(ctx.req, ctx.res);
const { phone, code } = ctx.guard.body;
const type = 'RegisterSms';
ctx.log(type, { sessionId: jti, phone, code });
assertThat(
!(await hasUserWithPhone(phone)),
@ -386,6 +397,7 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
await verifyPasscode(jti, PasscodeType.Register, code, { phone });
const id = await generateUserId();
ctx.log(type, { userId: id });
await insertUser({ id, primaryPhone: phone });
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
@ -400,6 +412,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
async (ctx, next) => {
const { jti } = await provider.interactionDetails(ctx.req, ctx.res);
const { email } = ctx.guard.body;
const type = 'RegisterEmailSendPasscode';
ctx.log(type, { sessionId: jti, email });
assertThat(
!(await hasUserWithEmail(email)),
@ -407,6 +421,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
);
const passcode = await createPasscode(jti, PasscodeType.Register, { email });
ctx.log(type, { passcode });
await sendPasscode(passcode);
ctx.status = 204;
@ -420,6 +436,8 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
async (ctx, next) => {
const { jti } = await provider.interactionDetails(ctx.req, ctx.res);
const { email, code } = ctx.guard.body;
const type = 'RegisterEmail';
ctx.log(type, { sessionId: jti, email, code });
assertThat(
!(await hasUserWithEmail(email)),
@ -428,6 +446,7 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
await verifyPasscode(jti, PasscodeType.Register, code, { email });
const id = await generateUserId();
ctx.log(type, { userId: id });
await insertUser({ id, primaryEmail: email });
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
@ -444,15 +463,18 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
}),
}),
async (ctx, next) => {
const { connectorId } = ctx.guard.body;
const { result } = await provider.interactionDetails(ctx.req, ctx.res);
const { jti, result } = await provider.interactionDetails(ctx.req, ctx.res);
// User can not register with social directly,
// need to try to sign in with social first, then confirm to register and continue,
// so the result is expected to be exists.
assertThat(result, 'session.connector_session_not_found');
const { connectorId } = ctx.guard.body;
const type = 'RegisterSocial';
ctx.log(type, { sessionId: jti, connectorId });
const userInfo = await getUserInfoFromInteractionResult(connectorId, result);
ctx.log(type, { userInfo });
assertThat(!(await hasUserWithIdentity(connectorId, userInfo.id)), 'user.identity_exists');
const id = await generateUserId();
@ -467,6 +489,7 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
},
},
});
ctx.log(type, { userId: id });
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
@ -482,15 +505,20 @@ export default function sessionRoutes<T extends AnonymousRouter>(router: T, prov
}),
}),
async (ctx, next) => {
const { connectorId } = ctx.guard.body;
const { result } = await provider.interactionDetails(ctx.req, ctx.res);
const { jti, result } = await provider.interactionDetails(ctx.req, ctx.res);
assertThat(result, 'session.connector_session_not_found');
assertThat(result.login?.accountId, 'session.unauthorized');
const userId = result.login?.accountId;
assertThat(userId, 'session.unauthorized');
const { connectorId } = ctx.guard.body;
const type = 'RegisterSocialBind';
ctx.log(type, { sessionId: jti, connectorId, userId });
const userInfo = await getUserInfoFromInteractionResult(connectorId, result);
const user = await findUserById(result.login.accountId);
ctx.log(type, { userInfo });
const updatedUser = await updateUserById(user.id, {
const user = await findUserById(userId);
const updatedUser = await updateUserById(userId, {
identities: {
...user.identities,
[connectorId]: { userId: userInfo.id, details: userInfo },

View file

@ -11,6 +11,46 @@ interface BaseLogPayload {
error?: string;
}
interface RegisterUsernamePasswordLogPayload extends BaseLogPayload {
userId?: string;
username?: string;
}
interface RegisterEmailSendPasscodeLogPayload extends BaseLogPayload {
email?: string;
passcode?: Passcode;
}
interface RegisterEmailLogPayload extends BaseLogPayload {
email?: string;
code?: string;
userId?: string;
}
interface RegisterSmsSendPasscodeLogPayload extends BaseLogPayload {
phone?: string;
passcode?: Passcode;
}
interface RegisterSmsLogPayload extends BaseLogPayload {
phone?: string;
code?: string;
userId?: string;
}
interface RegisterSocialBindLogPayload extends BaseLogPayload {
connectorId?: string;
userInfo?: object;
userId?: string;
}
interface RegisterSocialLogPayload extends RegisterSocialBindLogPayload {
code?: string;
state?: string;
redirectUri?: string;
redirectTo?: string;
}
interface SignInUsernamePasswordLogPayload extends BaseLogPayload {
userId?: string;
username?: string;
@ -52,6 +92,13 @@ interface SignInSocialLogPayload extends SignInSocialBindLogPayload {
}
export type LogPayloads = {
RegisterUsernamePassword: RegisterUsernamePasswordLogPayload;
RegisterEmailSendPasscode: RegisterEmailSendPasscodeLogPayload;
RegisterEmail: RegisterEmailLogPayload;
RegisterSmsSendPasscode: RegisterSmsSendPasscodeLogPayload;
RegisterSms: RegisterSmsLogPayload;
RegisterSocialBind: RegisterSocialBindLogPayload;
RegisterSocial: RegisterSocialLogPayload;
SignInUsernamePassword: SignInUsernamePasswordLogPayload;
SignInEmailSendPasscode: SignInEmailSendPasscodeLogPayload;
SignInEmail: SignInEmailLogPayload;