mirror of
https://github.com/wassname/talk.git
synced 2026-07-11 21:07:25 +08:00
Support rest and implement SignIn and SignUp Rest + Mutations
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@
|
||||
"compile:schema": "node ./scripts/generateSchemaTypes.js",
|
||||
"docz": "docz",
|
||||
"start": "node dist/index.js",
|
||||
"start:development": "cross-env NODE_ENV=development ts-node --project ./src/tsconfig.json -r tsconfig-paths/register ./src/index.ts",
|
||||
"start:development": "ts-node --project ./src/tsconfig.json -r tsconfig-paths/register ./src/index.ts",
|
||||
"start:webpackDevServer": "ts-node ./scripts/start.ts",
|
||||
"lint": "npm-run-all --parallel lint:*",
|
||||
"lint:server": "tslint --project ./src/tsconfig.json",
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import { signIn, SignInInput } from "talk-framework/rest";
|
||||
|
||||
export type SignInMutation = (input: SignInInput) => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: SignInInput,
|
||||
{ rest, postMessage }: 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);
|
||||
}
|
||||
}
|
||||
|
||||
export const withSignInMutation = createMutationContainer("signIn", commit);
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import { signUp, SignUpInput } from "talk-framework/rest";
|
||||
|
||||
export type SignUpMutation = (input: SignUpInput) => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: SignUpInput,
|
||||
{ rest, postMessage }: TalkContext
|
||||
) {
|
||||
try {
|
||||
const result = await signUp(rest, input);
|
||||
postMessage.send("setAuthToken", result.token, window.opener);
|
||||
window.close();
|
||||
} catch (err) {
|
||||
postMessage.send("authError", err.toString(), window.opener);
|
||||
}
|
||||
}
|
||||
|
||||
export const withSignUpMutation = createMutationContainer("signUp", commit);
|
||||
@@ -1 +1,3 @@
|
||||
export { withSetViewMutation, SetViewMutation } from "./SetViewMutation";
|
||||
export { withSignInMutation, SignInMutation } from "./SignInMutation";
|
||||
export { withSignUpMutation, SignUpMutation } from "./SignUpMutation";
|
||||
|
||||
@@ -21,7 +21,7 @@ const handleResp = (res: Response) => {
|
||||
if (res.status > 399) {
|
||||
return res.json().then((err: any) => {
|
||||
// TODO: sync error handling with server.
|
||||
const message = err.message || res.status;
|
||||
const message = err.message || err.error || res.status;
|
||||
const error = new Error(message);
|
||||
throw error;
|
||||
});
|
||||
@@ -43,7 +43,7 @@ export class RestClient {
|
||||
this.tokenGetter = tokenGetter;
|
||||
}
|
||||
|
||||
public fetch(path: string, options: PartialRequestInit): Promise<Response> {
|
||||
public fetch<T>(path: string, options: PartialRequestInit): Promise<T> {
|
||||
let opts = options;
|
||||
if (this.tokenGetter) {
|
||||
opts = merge({}, options, {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { commitLocalUpdate, Environment, RecordSource } from "relay-runtime";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { LOCAL_ID } from "talk-framework/lib/relay";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import { createRelayEnvironment } from "talk-framework/testHelpers";
|
||||
|
||||
import { commit } from "./SetAuthTokenMutation";
|
||||
@@ -16,18 +17,34 @@ beforeAll(() => {
|
||||
});
|
||||
|
||||
it("Sets auth token", async () => {
|
||||
const context = {
|
||||
localStorage: createInMemoryStorage(),
|
||||
};
|
||||
const authToken = "auth token";
|
||||
commit(environment, { authToken });
|
||||
commit(environment, { authToken }, context as any);
|
||||
expect(source.get(LOCAL_ID)!.authToken).toEqual(authToken);
|
||||
expect(context.localStorage.getItem("authToken")).toEqual(authToken);
|
||||
});
|
||||
|
||||
it("Removes auth token from localStorage", async () => {
|
||||
const context = {
|
||||
localStorage: createInMemoryStorage(),
|
||||
};
|
||||
localStorage.setItem("authToken", "tmp");
|
||||
commit(environment, { authToken: null }, context as any);
|
||||
expect(context.localStorage.getItem("authToken")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Should call gc", async () => {
|
||||
const context = {
|
||||
localStorage: createInMemoryStorage(),
|
||||
};
|
||||
commitLocalUpdate(environment, store => {
|
||||
store.create("should-disappear", "tmp");
|
||||
});
|
||||
const authToken = null;
|
||||
expect(source.get("should-disappear")).not.toBeUndefined();
|
||||
commit(environment, { authToken });
|
||||
commit(environment, { authToken }, context as any);
|
||||
await timeout();
|
||||
expect(source.get(LOCAL_ID)!.authToken).toEqual(authToken);
|
||||
expect(source.get("should-disappear")).toBeUndefined();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { commitLocalUpdate, Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
|
||||
|
||||
@@ -11,11 +12,17 @@ export type SetAuthTokenMutation = (input: SetAuthTokenInput) => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: SetAuthTokenInput
|
||||
input: SetAuthTokenInput,
|
||||
{ localStorage }: TalkContext
|
||||
) {
|
||||
return commitLocalUpdate(environment, store => {
|
||||
const record = store.get(LOCAL_ID)!;
|
||||
record.setValue(input.authToken, "authToken");
|
||||
if (input.authToken) {
|
||||
localStorage.setItem("authToken", input.authToken);
|
||||
} else {
|
||||
localStorage.removeItem("authToken");
|
||||
}
|
||||
|
||||
// Force gc to trigger.
|
||||
environment
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { RestClient } from "../lib/rest";
|
||||
|
||||
export interface SignInInput {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface SignInResponse {
|
||||
token: string;
|
||||
}
|
||||
|
||||
export default function signIn(rest: RestClient, input: SignInInput) {
|
||||
return rest.fetch("/tenant/auth/local", {
|
||||
return rest.fetch<SignInResponse>("/tenant/auth/local", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
});
|
||||
|
||||
@@ -6,8 +6,12 @@ export interface SignUpInput {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface SignUpResponse {
|
||||
token: string;
|
||||
}
|
||||
|
||||
export default function signUp(rest: RestClient, input: SignUpInput) {
|
||||
return rest.fetch("/tenant/auth/local/signup", {
|
||||
return rest.fetch<SignUpResponse>("/tenant/auth/local/signup", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Environment, RecordSource } from "relay-runtime";
|
||||
|
||||
import { LOCAL_ID } from "talk-framework/lib/relay";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import { createRelayEnvironment } from "talk-framework/testHelpers";
|
||||
|
||||
import onPostMessageSetAuthToken from "./onPostMessageSetAuthToken";
|
||||
@@ -24,6 +25,7 @@ it("Sets auth token", () => {
|
||||
},
|
||||
},
|
||||
relayEnvironment,
|
||||
localStorage: createInMemoryStorage(),
|
||||
};
|
||||
onPostMessageSetAuthToken(context as any);
|
||||
expect(source.get(LOCAL_ID)!.authToken).toEqual(token);
|
||||
|
||||
@@ -2,12 +2,10 @@ import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
|
||||
import { commit as setAuthToken } from "talk-framework/mutations/SetAuthTokenMutation";
|
||||
|
||||
export default function onPostMessageSetAuthToken({
|
||||
relayEnvironment,
|
||||
postMessage,
|
||||
}: TalkContext) {
|
||||
export default function onPostMessageSetAuthToken(ctx: TalkContext) {
|
||||
const { relayEnvironment, postMessage } = ctx;
|
||||
// Auth popup will use this to handle a successful login.
|
||||
postMessage!.on("setAuthToken", (authToken: string) => {
|
||||
setAuthToken(relayEnvironment, { authToken });
|
||||
setAuthToken(relayEnvironment, { authToken }, ctx);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ export default async function initLocalState(
|
||||
{ localStorage }: TalkContext
|
||||
) {
|
||||
commitLocalUpdate(environment, s => {
|
||||
// TODO: (cvle) move local, auth token and network initialization to framework.
|
||||
const root = s.getRoot();
|
||||
|
||||
// Create the Local Record which is the Root for the client states.
|
||||
|
||||
Reference in New Issue
Block a user