[next] Cookie Support (#2339)

* feat: added cookie support to coral

* feat: adapt client to use cookies

* fix: safari input styles

* fix: lint

* fix: linting

* fix: support clearing cookies properly, oauth

* feat: support cookies for websocket upgrade requests

* fix: lint

* fix: tests
This commit is contained in:
Wyatt Johnson
2019-06-25 21:48:58 +02:00
committed by Vinh
parent 3576b6a943
commit e72b15c505
79 changed files with 375 additions and 278 deletions
@@ -1,12 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`get auth token from url 1`] = `
exports[`get access token from url 1`] = `
"{
\\"__id\\": \\"client:root.local\\",
\\"__typename\\": \\"Local\\",
\\"accessToken\\": \\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzMWIyNjU5MS00ZTlhLTQzODgtYTdmZi1lMWJkYzVkOTdjY2UifQ==\\",
\\"accessTokenJTI\\": \\"31b26591-4e9a-4388-a7ff-e1bdc5d97cce\\",
\\"loggedIn\\": true,
\\"view\\": \\"SIGN_IN\\",
\\"error\\": null
}"
@@ -27,7 +26,6 @@ exports[`init local state 1`] = `
\\"accessToken\\": \\"\\",
\\"accessTokenExp\\": null,
\\"accessTokenJTI\\": null,
\\"loggedIn\\": false,
\\"view\\": \\"SIGN_IN\\",
\\"error\\": null
}
@@ -39,7 +39,7 @@ it("set view from query", async () => {
restoreHistoryLocation();
});
it("get auth token from url", async () => {
it("get access token from url", async () => {
const restoreHistoryLocation = replaceHistoryLocation(
`http://localhost/#accessToken=${createAccessToken()}`
);
-1
View File
@@ -11,7 +11,6 @@ type Local {
accessToken: String
accessTokenExp: Int
accessTokenJTI: String
loggedIn: Boolean!
view: View!
error: String
}
@@ -340,7 +340,7 @@ exports[`auth configuration renders all auth enabled 1`] = `
>
<a
className="TextLink-root"
href="http://localhost/?view=FORGOT_PASSWORD#accessToken=access-token"
href="http://localhost/?view=FORGOT_PASSWORD"
onClick={[Function]}
>
Forgot your password?
@@ -122,7 +122,7 @@ it("do not render createPassword view when local auth is disabled", async () =>
await wait(() => expect(windowMock.closeStub.called).toBe(true));
});
it("send back auth token", async () => {
it("send back access token", async () => {
const { context } = await createTestRenderer({
Query: {
viewer: {
+10 -4
View File
@@ -1,8 +1,9 @@
import { get } from "lodash";
import sinon from "sinon";
import sinon, { SinonStub } from "sinon";
import { pureMerge } from "coral-common/utils";
import {
createAccessToken,
toJSON,
wait,
waitForElement,
@@ -165,7 +166,7 @@ it("shows server error", async () => {
it("submits form successfully", async () => {
const { form, context } = await createTestRenderer();
const { getByLabelText } = within(form!);
const accessToken = "access-token";
const accessToken = createAccessToken();
const emailAddressField = getByLabelText("Email Address");
const passwordField = getByLabelText("Password");
const submitButton = form!.find(
@@ -198,8 +199,13 @@ it("submits form successfully", async () => {
expect(toJSON(form!)).toMatchSnapshot();
// Wait for window hash to contain a token.
await wait(() => expect(location.hash).toBe(`#accessToken=${accessToken}`));
// Wait for new session to start.
await wait(() =>
expect((context.clearSession as SinonStub).calledWith(accessToken)).toBe(
true
)
);
restMock.verify();
});
+9 -4
View File
@@ -1,7 +1,8 @@
import { get, merge } from "lodash";
import sinon from "sinon";
import sinon, { SinonStub } from "sinon";
import {
createAccessToken,
toJSON,
wait,
waitForElement,
@@ -186,7 +187,7 @@ it("shows server error", async () => {
it("submits form successfully", async () => {
const { context, main, form } = await createTestRenderer();
const { getByLabelText } = within(form!);
const accessToken = "access-token";
const accessToken = createAccessToken();
const emailAddressField = getByLabelText("Email Address");
const usernameField = getByLabelText("Username");
const passwordField = getByLabelText("Password");
@@ -223,8 +224,12 @@ it("submits form successfully", async () => {
expect(toJSON(main)).toMatchSnapshot();
// Wait for window hash to contain a token.
await wait(() => expect(location.hash).toBe(`#accessToken=${accessToken}`));
// Wait for new session to start.
await wait(() =>
expect((context.clearSession as SinonStub).calledWith(accessToken)).toBe(
true
)
);
restMock.verify();
});
@@ -13,12 +13,7 @@ export async function commit(
{ rest, clearSession }: CoralContext
) {
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 = `accessToken=${result.token}`;
await clearSession();
// TODO: (cvle) A better way would be if `context.clearSession` would return the new session and
// we set the accessToken directly in there.
await clearSession(result.token);
}
export const withSignInMutation = createMutationContainer("signIn", commit);
@@ -16,10 +16,7 @@ export async function commit(
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 = `accessToken=${result.token}`;
await clearSession();
await clearSession(result.token);
}
export const withSignUpMutation = createMutationContainer("signUp", commit);