Skip to content

Commit

Permalink
feat(login): support google login (#1465)
Browse files Browse the repository at this point in the history
* feat(flat-web): google login

* feat(desktop): google login

* chore: remove unused code

* chore: remove spell check since it already exist in lint

* Update desktop/renderer-app/src/pages/LoginPage/googleLogin.ts

Co-authored-by: Black-Hole <158blackhole@gmail.com>

* chore: compact code

Co-authored-by: Black-Hole <158blackhole@gmail.com>
  • Loading branch information
hyrious and BlackHole1 authored Apr 7, 2022
1 parent c2088b0 commit c9c1a34
Show file tree
Hide file tree
Showing 23 changed files with 215 additions and 26 deletions.
1 change: 0 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

pnpm check-spelling
pnpm lint
1 change: 1 addition & 0 deletions config/America/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ AGORA_APP_ID=931b86d6781e49a2a255db4ce6e8e804
GITHUB_CLIENT_ID=0ac608815326aead5db7
WECHAT_APP_ID=wx1133c2153a45e9b8
AGORA_OAUTH_CLIENT_ID=flat-dev
GOOGLE_OAUTH_CLIENT_ID=273996094508-p97og69ojac5ja0khn1rvmi3tb7vgfgm.apps.googleusercontent.com

CLOUD_STORAGE_OSS_ALIBABA_ACCESS_KEY=LTAI5t9Gb6tzQzzLmB6cTVf7
CLOUD_STORAGE_OSS_ALIBABA_BUCKET=flat-storage
Expand Down
1 change: 1 addition & 0 deletions config/America/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ AGORA_APP_ID=931b86d6781e49a2a255db4ce6e8e804
GITHUB_CLIENT_ID=da83d7e14217594fba46
WECHAT_APP_ID=wx96d522d69d384cce
AGORA_OAUTH_CLIENT_ID=flat
GOOGLE_OAUTH_CLIENT_ID=273996094508-2rpraucen77a1o5dul5ftrua5k3og157.apps.googleusercontent.com

CLOUD_STORAGE_OSS_ALIBABA_ACCESS_KEY=LTAI5t9Gb6tzQzzLmB6cTVf7
CLOUD_STORAGE_OSS_ALIBABA_BUCKET=flat-storage
Expand Down
1 change: 1 addition & 0 deletions config/China/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ AGORA_APP_ID=931b86d6781e49a2a255db4ce6e8e804
GITHUB_CLIENT_ID=9821657775fbc74773f1
WECHAT_APP_ID=wx1133c2153a45e9b8
AGORA_OAUTH_CLIENT_ID=flat-dev
GOOGLE_OAUTH_CLIENT_ID=273996094508-p97og69ojac5ja0khn1rvmi3tb7vgfgm.apps.googleusercontent.com

CLOUD_STORAGE_OSS_ALIBABA_ACCESS_KEY=LTAI5t9Gb6tzQzzLmB6cTVf7
CLOUD_STORAGE_OSS_ALIBABA_BUCKET=flat-storage
Expand Down
1 change: 1 addition & 0 deletions config/China/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ AGORA_APP_ID=931b86d6781e49a2a255db4ce6e8e804
GITHUB_CLIENT_ID=71a29285a437998bdfe0
WECHAT_APP_ID=wx96d522d69d384cce
AGORA_OAUTH_CLIENT_ID=flat
GOOGLE_OAUTH_CLIENT_ID=273996094508-2rpraucen77a1o5dul5ftrua5k3og157.apps.googleusercontent.com

CLOUD_STORAGE_OSS_ALIBABA_ACCESS_KEY=LTAI5t9Gb6tzQzzLmB6cTVf7
CLOUD_STORAGE_OSS_ALIBABA_BUCKET=flat-storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const FLAT_SERVER_VERSIONS = {

export const FLAT_SERVER_LOGIN = {
GITHUB_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/github/callback`,
GOOGLE_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/google/callback`,
WECHAT_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/weChat/web/callback`,
} as const;

Expand Down
4 changes: 4 additions & 0 deletions desktop/renderer-app/src/constants/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const GITHUB = Object.freeze({
CLIENT_ID: process.env.GITHUB_CLIENT_ID,
});

export const GOOGLE = Object.freeze({
CLIENT_ID: process.env.GOOGLE_OAUTH_CLIENT_ID,
});

export const FLAT_SERVER_DOMAIN = process.env.FLAT_SERVER_DOMAIN;
export const FLAT_WEB_DOMAIN = process.env.FLAT_WEB_DOMAIN;

Expand Down
4 changes: 2 additions & 2 deletions desktop/renderer-app/src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export const HomePage = observer<HomePageProps>(function HomePage() {

try {
await loginCheck();
globalStore.lastLoginCheck = Date.now();
globalStore.updateLastLoginCheck(Date.now());
return true;
} catch (e) {
globalStore.lastLoginCheck = null;
globalStore.updateLastLoginCheck(null);
console.error(e);
errorTips(e as Error);
}
Expand Down
53 changes: 53 additions & 0 deletions desktop/renderer-app/src/pages/LoginPage/googleLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { setAuthUUID, loginProcess } from "../../api-middleware/flatServer";
import { v4 as uuidv4 } from "uuid";
import { LoginExecutor } from "./utils";
import { shell } from "electron";
import { errorTips } from "../../components/Tips/ErrorTips";
import { FLAT_SERVER_LOGIN } from "../../api-middleware/flatServer/constants";
import { GOOGLE } from "../../constants/process";

// @TODO: migrate to new google login api before 2023. @hyrious
// https://developers.google.com/identity/gsi/web
export const googleLogin: LoginExecutor = onSuccess => {
let timer = NaN;
const authUUID = uuidv4();
const scopes = ["openid", "https://www.googleapis.com/auth/userinfo.profile"];

function getGoogleURL(authUUID: string): string {
const redirectURL = encodeURIComponent(FLAT_SERVER_LOGIN.GOOGLE_CALLBACK);
const scope = encodeURIComponent(scopes.join(" "));
return `https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=online&scope=${scope}&client_id=${GOOGLE.CLIENT_ID}&redirect_uri=${redirectURL}&state=${authUUID}`;
}

void (async () => {
try {
await setAuthUUID(authUUID);
} catch (err) {
errorTips(err);
return;
}

void shell.openExternal(getGoogleURL(authUUID));

const googleLoginProcessRequest = async (): Promise<void> => {
try {
const data = await loginProcess(authUUID);

if (!data.name) {
timer = window.setTimeout(googleLoginProcessRequest, 2000);
return;
}

onSuccess(data);
} catch (err) {
errorTips(err);
}
};

void googleLoginProcessRequest();
})();

return () => {
window.clearTimeout(timer);
};
};
36 changes: 26 additions & 10 deletions desktop/renderer-app/src/pages/LoginPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@ import "./index.less";

import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
import { constants } from "flat-types";
import { useTranslation } from "react-i18next";
import { observer } from "mobx-react-lite";
import { ipcAsyncByMainWindow, ipcSyncByApp } from "../../utils/ipc";
import { message } from "antd";
import { LoginPanel, LoginButton, LoginButtonProviderType } from "flat-components";
import { LoginDisposer } from "./utils";
import { githubLogin } from "./githubLogin";
import WeChatLogin from "./WeChatLogin";
import { googleLogin } from "./googleLogin";
import { ipcAsyncByMainWindow, ipcSyncByApp } from "../../utils/ipc";
import { LoginDisposer } from "./utils";
import { RouteNameType, usePushHistory } from "../../utils/routes";
import { GlobalStoreContext } from "../../components/StoreProvider";
import { AppUpgradeModal, AppUpgradeModalProps } from "../../components/AppUpgradeModal";
import { runtime } from "../../utils/runtime";
import { useSafePromise } from "../../utils/hooks/lifecycle";
import { useTranslation } from "react-i18next";
import {
PRIVACY_URL_EN,
PRIVACY_URL_CN,
SERVICE_URL_EN,
SERVICE_URL_CN,
} from "../../constants/process";
import { message } from "antd";
import WeChatLogin from "./WeChatLogin";

export const LoginPage = observer(function LoginPage() {
const { i18n } = useTranslation();
Expand Down Expand Up @@ -81,6 +82,13 @@ export const LoginPage = observer(function LoginPage() {
});
return;
}
case "google": {
loginDisposer.current = googleLogin(async authData => {
globalStore.updateUserInfo(authData);
pushHistory(RouteNameType.HomePage);
});
return;
}
case "wechat": {
setWeChatLogin(true);
return;
Expand All @@ -105,11 +113,19 @@ export const LoginPage = observer(function LoginPage() {
function renderButtonList(): React.ReactNode {
return (
<>
<LoginButton
provider="wechat"
text={i18n.t("login-wechat")}
onLogin={handleLogin}
/>
{process.env.FLAT_REGION === "America" ? (
<LoginButton
provider="google"
text={i18n.t("login-google")}
onLogin={handleLogin}
/>
) : (
<LoginButton
provider="wechat"
text={i18n.t("login-wechat")}
onLogin={handleLogin}
/>
)}
<LoginButton
provider="github"
text={i18n.t("login-github")}
Expand Down
4 changes: 4 additions & 0 deletions desktop/renderer-app/src/stores/global-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export class GlobalStore {
this.userInfo = userInfo;
};

public updateLastLoginCheck = (val: number | null): void => {
this.lastLoginCheck = val;
};

public updateToken = (
config: Partial<
Pick<
Expand Down
1 change: 1 addition & 0 deletions desktop/renderer-app/typings/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ declare namespace NodeJS {
AGORA_APP_ID: string;

GITHUB_CLIENT_ID: string;
GOOGLE_OAUTH_CLIENT_ID: string;

WECHAT_APP_ID: string;
FLAT_SERVER_DOMAIN: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

.login-channel-github {
margin-bottom: 12px;

&.ant-btn {
background: #24292e;

Expand All @@ -64,3 +64,20 @@
}
}
}

.login-channel-google {
margin-bottom: 12px;

&.ant-btn {
background: #fff;
color: #1b1f22;
border: 1px solid #595d60;

&:hover {
border: 1px solid #1b1f22;
}
&:active {
border: 1px solid #1b1f22;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import React from "react";
import wechatSVG from "./icons/wechat.svg";
import agoraSVG from "./icons/agora.svg";
import githubSVG from "./icons/github.svg";
import googleSVG from "./icons/google.svg";
import "./index.less";

export type LoginButtonProviderType = "wechat" | "github" | "agora";
export type LoginButtonProviderType = "wechat" | "github" | "agora" | "google";

export type LoginButtonProps = {
provider: LoginButtonProviderType;
Expand All @@ -17,6 +18,7 @@ const svgDict: Record<LoginButtonProviderType, string> = {
wechat: wechatSVG,
agora: agoraSVG,
github: githubSVG,
google: googleSVG,
};

export const LoginButton: React.FC<LoginButtonProps> = ({ provider, onLogin, text }) => {
Expand Down
1 change: 1 addition & 0 deletions packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"join-and-book-by-room-uuid": "Can join and book by room ID",
"copy": "Copy",
"login-github": "Sign In with GitHub",
"login-google": "Sign In with Google",
"login-wechat": "Sign In with WeChat",
"login-agora": "Sign In with Agora",
"agree-terms": "Please agree to the terms of service first",
Expand Down
1 change: 1 addition & 0 deletions packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"copy": "复制",
"login-wechat": "微信登录",
"login-github": "GitHub 登录",
"login-google": "Google 登录",
"login-agora": "声网登录",
"app-welcome": "欢迎使用 {{appName}}",
"online-interaction-to-synchronize-ideas": "在线互动,让想法同步",
Expand Down
1 change: 1 addition & 0 deletions web/flat-web/src/api-middleware/flatServer/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const FLAT_SERVER_VERSIONS = {
export const FLAT_SERVER_LOGIN = {
AGORA_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/agora/callback`,
GITHUB_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/github/callback?platform=web`,
GOOGLE_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/google/callback`,
WECHAT_CALLBACK: `${FLAT_SERVER_VERSIONS.V1}/login/weChat/web/callback`,
} as const;

Expand Down
4 changes: 4 additions & 0 deletions web/flat-web/src/constants/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export const GITHUB = Object.freeze({
CLIENT_ID: process.env.GITHUB_CLIENT_ID,
});

export const GOOGLE = Object.freeze({
CLIENT_ID: process.env.GOOGLE_OAUTH_CLIENT_ID,
});

export const FLAT_SERVER_DOMAIN = process.env.FLAT_SERVER_DOMAIN;
export const FLAT_WEB_DOMAIN = process.env.FLAT_WEB_DOMAIN;

Expand Down
4 changes: 2 additions & 2 deletions web/flat-web/src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ export const HomePage = observer(function HomePage() {

try {
await loginCheck();
globalStore.lastLoginCheck = Date.now();
globalStore.updateLastLoginCheck(Date.now());
return true;
} catch (e) {
globalStore.lastLoginCheck = null;
globalStore.updateLastLoginCheck(null);
console.error(e);
errorTips(e as Error);
}
Expand Down
52 changes: 52 additions & 0 deletions web/flat-web/src/pages/LoginPage/googleLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { setAuthUUID, loginProcess } from "../../api-middleware/flatServer";
import { v4 as uuidv4 } from "uuid";
import { LoginExecutor } from "./utils";
import { errorTips } from "../../components/Tips/ErrorTips";
import { FLAT_SERVER_LOGIN } from "../../api-middleware/flatServer/constants";
import { GOOGLE } from "../../constants/process";

// @TODO: migrate to new google login api before 2023
// https://developers.google.com/identity/gsi/web
export const googleLogin: LoginExecutor = onSuccess => {
let timer = NaN;
const authUUID = uuidv4();
const scopes = ["openid", "https://www.googleapis.com/auth/userinfo.profile"];

function getGoogleURL(authUUID: string): string {
const redirectURL = encodeURIComponent(FLAT_SERVER_LOGIN.GOOGLE_CALLBACK);
const scope = encodeURIComponent(scopes.join(" "));
return `https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=online&scope=${scope}&client_id=${GOOGLE.CLIENT_ID}&redirect_uri=${redirectURL}&state=${authUUID}`;
}

void (async () => {
try {
await setAuthUUID(authUUID);
} catch (err) {
errorTips(err);
return;
}

void window.open(getGoogleURL(authUUID));

const googleLoginProcessRequest = async (): Promise<void> => {
try {
const data = await loginProcess(authUUID);

if (!data.name) {
timer = window.setTimeout(googleLoginProcessRequest, 2000);
return;
}

onSuccess(data);
} catch (err) {
errorTips(err);
}
};

void googleLoginProcessRequest();
})();

return () => {
window.clearTimeout(timer);
};
};
Loading

0 comments on commit c9c1a34

Please sign in to comment.