[next] Email (#2261)

* feat: suspending, banning, now propogation

* feat: added email rendering + localization support

* fix: fix related to lib

* refactor: moved juicer to queue task

* refactor: cleanup of job processor

* refactor: improved error messaging around failed email

* feat: initial forgot passwor impl

* fix: fixed rebase errors

* feat: send back Content-Language header with requests

* feat: added ban email

* feat: implemented forgotten password API

* fix: linting

* feat: support more emails

* fix: promise patches

* feat: initial confirm email API

* feat: added rate limiting

* feat: added URL support

* feat: added email docs

* fix: updated docs

* chore: documentation review

* fix: fixed build bug

* feat: implement forgot password in auth popup

* test: add tests + fixes

* chore: rename StatelessComponent to FunctionComponent

* fix: types and test fixes

* chore: upgrade deps

* fix: THANK YOU TESTS FOR SAVING MY A**

* chore: reorder imports

* chore: remove obsolete !

* feat: implement accounts bundle

* refactor: review suggestion

* fix: rebase upgrade error

* fix: rebase bug

* feat: reset password link support

* test: add tests for account password reset page

* fix: remove redirect uri

* fix: revert local state changes
This commit is contained in:
Wyatt Johnson
2019-05-09 22:54:56 +02:00
committed by Kiwi
parent 945bd7f2b0
commit df57b4eb17
487 changed files with 6794 additions and 2431 deletions
@@ -0,0 +1,12 @@
import { pick } from "lodash";
import { createMutation } from "talk-framework/lib/relay";
import { forgotPassword, ForgotPasswordInput } from "talk-framework/rest";
const ForgotPasswordMutation = createMutation(
"forgotPassword",
(_, input: ForgotPasswordInput, { rest }) =>
forgotPassword(rest, pick(input, ["email"]))
);
export default ForgotPasswordMutation;
@@ -3,7 +3,7 @@ import { Environment, RecordSource } from "relay-runtime";
import { LOCAL_ID } from "talk-framework/lib/relay";
import { createRelayEnvironment } from "talk-framework/testHelpers";
import { commit } from "./SetViewMutation";
import SetViewMutation from "./SetViewMutation";
let environment: Environment;
const source: RecordSource = new RecordSource();
@@ -16,6 +16,6 @@ beforeAll(() => {
it("Sets view", () => {
const view = "SIGN_UP";
commit(environment, { view }, {} as any);
SetViewMutation.commit(environment, { view }, {} as any);
expect(source.get(LOCAL_ID)!.view).toEqual(view);
});
@@ -1,32 +1,56 @@
import { commitLocalUpdate, Environment } from "relay-runtime";
import { TalkContext } from "talk-framework/lib/bootstrap";
import { createMutationContainer } from "talk-framework/lib/relay";
import { createMutation } from "talk-framework/lib/relay";
import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
export type View =
| "SIGN_IN"
| "SIGN_UP"
| "FORGOT_PASSWORD"
| "ADD_EMAIL_ADDRESS"
| "CREATE_USERNAME"
| "CREATE_PASSWORD";
export interface SetViewInput {
// TODO: replace with generated typescript types.
view:
| "SIGN_IN"
| "SIGN_UP"
| "FORGOT_PASSWORD"
| "RESET_PASSWORD"
| "ADD_EMAIL_ADDRESS"
| "CREATE_USERNAME"
| "CREATE_PASSWORD";
view: View;
history?: "push" | "replace";
}
export type SetViewMutation = (input: SetViewInput) => Promise<void>;
const SetViewMutation = createMutation(
"setView",
(environment: Environment, input: SetViewInput) => {
return commitLocalUpdate(environment, store => {
const record = store.get(LOCAL_ID)!;
export async function commit(
environment: Environment,
input: SetViewInput,
{ pym }: TalkContext
) {
return commitLocalUpdate(environment, store => {
const record = store.get(LOCAL_ID)!;
record.setValue(input.view, "view");
});
}
if (input.history) {
const newLocation = window.location.href.replace(
/\?[^#]*/,
`?view=${input.view}`
);
const previousState = window.history.state;
switch (input.history) {
case "push":
window.history.pushState(
previousState,
document.title,
newLocation
);
break;
case "replace":
window.history.replaceState(
previousState,
document.title,
newLocation
);
break;
default:
}
}
export const withSetViewMutation = createMutationContainer("setView", commit);
record.setValue(input.view, "view");
});
}
);
export default SetViewMutation;
+2 -1
View File
@@ -1,4 +1,4 @@
export { withSetViewMutation, SetViewMutation } from "./SetViewMutation";
export { default as SetViewMutation } from "./SetViewMutation";
export { withSignInMutation, SignInMutation } from "./SignInMutation";
export {
withCompleteAccountMutation,
@@ -18,3 +18,4 @@ export {
withSetPasswordMutation,
SetPasswordMutation,
} from "./SetPasswordMutation";
export { default as ForgotPasswordMutation } from "./ForgotPasswordMutation";