mirror of
https://github.com/wassname/talk.git
synced 2026-08-02 13:10:23 +08:00
[next] Auth Popup v2 (#2101)
* feat: Implement new Sign In view * feat: Move forgot + resetPassword to new design * feat: Implement sign up with new design * fix: narrow gutter * test: add unit tests * test: integration tests * feat: support show / hide password * feat: support oauth2 flow * feat: add views for user completion * feat: implement oauth2 sign up * test: fix snapshots * fix: lint * fix: get more complete mutation response * fix: removed array of OIDC integrations * fix: renamed resolver function * fix: adapt oidc client implementation * fix: targetFilter should be stream on signup * fix: removed unneeded message * fix: moved password into local profile * fix: made username optional, removed valid null value * fix: linting * fix: respect targetFilter * feat: support user registration mutations - Added `setUsername` - Added `setEmail` - Added `setPassword` - Added `permit` to `@auth` - Added `email` to `User` * fix: fixed issue with query * feat: added user password update * feat: complete sign in mutation * fix: adapt some rebasing gitches * test: improve tests * test: unittest for setting auth token * fix: failing tests * test: move most tests from enzyme to react-test-renderer * fix: remove schema warnings in tests * test: improve window mock * test: test different social login configurations * test: test social logins for sign up * fix: use htmlFor instead of for * test: more feature tests * feat: always go through account completion * test: feature test account completion * feat: addtional account completion test * Update start.ts * chore: refactor auth token retrieval logic
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
|
||||
export interface CompleteAccountInput {
|
||||
authToken: string;
|
||||
}
|
||||
export type CompleteAccountMutation = (
|
||||
input: CompleteAccountInput
|
||||
) => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: CompleteAccountInput,
|
||||
{ postMessage }: TalkContext
|
||||
) {
|
||||
postMessage.send("setAuthToken", input.authToken, window.opener);
|
||||
window.close();
|
||||
}
|
||||
|
||||
export const withCompleteAccountMutation = createMutationContainer(
|
||||
"completeAccount",
|
||||
commit
|
||||
);
|
||||
@@ -0,0 +1,46 @@
|
||||
import { graphql } from "react-relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
commitMutationPromiseNormalized,
|
||||
createMutationContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { Omit } from "talk-framework/types";
|
||||
|
||||
import { SetEmailMutation as MutationTypes } from "talk-auth/__generated__/SetEmailMutation.graphql";
|
||||
|
||||
export type SetEmailInput = Omit<
|
||||
MutationTypes["variables"]["input"],
|
||||
"clientMutationId"
|
||||
>;
|
||||
|
||||
const mutation = graphql`
|
||||
mutation SetEmailMutation($input: SetEmailInput!) {
|
||||
setEmail(input: $input) {
|
||||
user {
|
||||
email
|
||||
}
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let clientMutationId = 0;
|
||||
|
||||
function commit(environment: Environment, input: SetEmailInput) {
|
||||
return commitMutationPromiseNormalized<MutationTypes>(environment, {
|
||||
mutation,
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const withSetEmailMutation = createMutationContainer("setEmail", commit);
|
||||
|
||||
export type SetEmailMutation = (
|
||||
input: SetEmailInput
|
||||
) => Promise<MutationTypes["response"]["setEmail"]>;
|
||||
@@ -0,0 +1,51 @@
|
||||
import { graphql } from "react-relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
commitMutationPromiseNormalized,
|
||||
createMutationContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { Omit } from "talk-framework/types";
|
||||
|
||||
import { SetPasswordMutation as MutationTypes } from "talk-auth/__generated__/SetPasswordMutation.graphql";
|
||||
|
||||
export type SetPasswordInput = Omit<
|
||||
MutationTypes["variables"]["input"],
|
||||
"clientMutationId"
|
||||
>;
|
||||
|
||||
const mutation = graphql`
|
||||
mutation SetPasswordMutation($input: SetPasswordInput!) {
|
||||
setPassword(input: $input) {
|
||||
user {
|
||||
profiles {
|
||||
__typename
|
||||
}
|
||||
}
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let clientMutationId = 0;
|
||||
|
||||
function commit(environment: Environment, input: SetPasswordInput) {
|
||||
return commitMutationPromiseNormalized<MutationTypes>(environment, {
|
||||
mutation,
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const withSetPasswordMutation = createMutationContainer(
|
||||
"setPassword",
|
||||
commit
|
||||
);
|
||||
|
||||
export type SetPasswordMutation = (
|
||||
input: SetPasswordInput
|
||||
) => Promise<MutationTypes["response"]["setPassword"]>;
|
||||
@@ -0,0 +1,49 @@
|
||||
import { graphql } from "react-relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
commitMutationPromiseNormalized,
|
||||
createMutationContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { Omit } from "talk-framework/types";
|
||||
|
||||
import { SetUsernameMutation as MutationTypes } from "talk-auth/__generated__/SetUsernameMutation.graphql";
|
||||
|
||||
export type SetUsernameInput = Omit<
|
||||
MutationTypes["variables"]["input"],
|
||||
"clientMutationId"
|
||||
>;
|
||||
|
||||
const mutation = graphql`
|
||||
mutation SetUsernameMutation($input: SetUsernameInput!) {
|
||||
setUsername(input: $input) {
|
||||
user {
|
||||
username
|
||||
}
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let clientMutationId = 0;
|
||||
|
||||
function commit(environment: Environment, input: SetUsernameInput) {
|
||||
return commitMutationPromiseNormalized<MutationTypes>(environment, {
|
||||
mutation,
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const withSetUsernameMutation = createMutationContainer(
|
||||
"setUsername",
|
||||
commit
|
||||
);
|
||||
|
||||
export type SetUsernameMutation = (
|
||||
input: SetUsernameInput
|
||||
) => Promise<MutationTypes["response"]["setUsername"]>;
|
||||
@@ -6,7 +6,14 @@ import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
|
||||
|
||||
export interface SetViewInput {
|
||||
// TODO: replace with generated typescript types.
|
||||
view: "SIGN_IN" | "SIGN_UP" | "FORGOT_PASSWORD" | "RESET_PASSWORD";
|
||||
view:
|
||||
| "SIGN_IN"
|
||||
| "SIGN_UP"
|
||||
| "FORGOT_PASSWORD"
|
||||
| "RESET_PASSWORD"
|
||||
| "ADD_EMAIL_ADDRESS"
|
||||
| "CREATE_USERNAME"
|
||||
| "CREATE_PASSWORD";
|
||||
}
|
||||
|
||||
export type SetViewMutation = (input: SetViewInput) => Promise<void>;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { pick } from "lodash";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
@@ -9,16 +10,13 @@ export type SignInMutation = (input: SignInInput) => Promise<void>;
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: SignInInput,
|
||||
{ rest, postMessage }: TalkContext
|
||||
{ rest, clearSession }: TalkContext
|
||||
) {
|
||||
try {
|
||||
const result = await signIn(rest, input);
|
||||
postMessage.send("setAuthToken", result.token, window.opener);
|
||||
window.close();
|
||||
} catch (err) {
|
||||
postMessage.send("authError", err.toString(), window.opener);
|
||||
throw err;
|
||||
}
|
||||
const result = await signIn(rest, pick(input, ["email", "password"]));
|
||||
// Put the token on the hash and clean the session.
|
||||
// It'll be picked up by initLocalState.
|
||||
location.hash = result.token;
|
||||
clearSession();
|
||||
}
|
||||
|
||||
export const withSignInMutation = createMutationContainer("signIn", commit);
|
||||
|
||||
@@ -10,19 +10,16 @@ export type SignUpMutation = (input: SignUpInput) => Promise<void>;
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: SignUpInput,
|
||||
{ rest, postMessage }: TalkContext
|
||||
{ rest, clearSession }: TalkContext
|
||||
) {
|
||||
try {
|
||||
const result = await signUp(
|
||||
rest,
|
||||
pick(input, "email", "password", "username")
|
||||
);
|
||||
postMessage.send("setAuthToken", result.token, window.opener);
|
||||
window.close();
|
||||
} catch (err) {
|
||||
postMessage.send("authError", err.toString(), window.opener);
|
||||
throw err;
|
||||
}
|
||||
const result = await signUp(
|
||||
rest,
|
||||
pick(input, ["email", "password", "username"])
|
||||
);
|
||||
// Put the token on the hash and clean the session.
|
||||
// It'll be picked up by initLocalState.
|
||||
location.hash = result.token;
|
||||
clearSession();
|
||||
}
|
||||
|
||||
export const withSignUpMutation = createMutationContainer("signUp", commit);
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
export { withSetViewMutation, SetViewMutation } from "./SetViewMutation";
|
||||
export { withSignInMutation, SignInMutation } from "./SignInMutation";
|
||||
export {
|
||||
withCompleteAccountMutation,
|
||||
CompleteAccountMutation,
|
||||
} from "./CompleteAccountMutation";
|
||||
export { withSignUpMutation, SignUpMutation } from "./SignUpMutation";
|
||||
export { withSetEmailMutation, SetEmailMutation } from "./SetEmailMutation";
|
||||
export {
|
||||
withSetUsernameMutation,
|
||||
SetUsernameMutation,
|
||||
} from "./SetUsernameMutation";
|
||||
export {
|
||||
withSetPasswordMutation,
|
||||
SetPasswordMutation,
|
||||
} from "./SetPasswordMutation";
|
||||
|
||||
Reference in New Issue
Block a user