diff --git a/app/containers/LoginServices.tsx b/app/containers/LoginServices.tsx index 4495c7e888..ece543e088 100644 --- a/app/containers/LoginServices.tsx +++ b/app/containers/LoginServices.tsx @@ -3,6 +3,7 @@ import { Animated, Easing, Linking, StyleSheet, Text, View } from 'react-native' import { connect } from 'react-redux'; import { Base64 } from 'js-base64'; import * as AppleAuthentication from 'expo-apple-authentication'; +import { StackNavigationProp } from '@react-navigation/stack'; import { withTheme } from '../theme'; import sharedStyles from '../views/Styles'; @@ -15,6 +16,9 @@ import random from '../utils/random'; import { events, logEvent } from '../utils/log'; import RocketChat from '../lib/rocketchat'; import { CustomIcon } from '../lib/Icons'; +import { IServices } from '../selectors/login'; +import { OutsideParamList } from '../stacks/types'; +import { IApplicationState } from '../definitions'; const BUTTON_HEIGHT = 48; const SERVICE_HEIGHT = 58; @@ -58,31 +62,40 @@ const styles = StyleSheet.create({ }); interface IOpenOAuth { - url?: string; + url: string; ssoToken?: string; authType?: string; } -interface IService { +interface IItemService { name: string; service: string; authType: string; buttonColor: string; buttonLabelColor: string; + clientConfig: { provider: string }; + serverURL: string; + authorizePath: string; + clientId: string; + scope: string; +} + +interface IOauthProvider { + [key: string]: () => void; + facebook: () => void; + github: () => void; + gitlab: () => void; + google: () => void; + linkedin: () => void; + 'meteor-developer': () => void; + twitter: () => void; + wordpress: () => void; } interface ILoginServicesProps { - navigation: any; + navigation: StackNavigationProp; server: string; - services: { - facebook: { clientId: string }; - github: { clientId: string }; - gitlab: { clientId: string }; - google: { clientId: string }; - linkedin: { clientId: string }; - 'meteor-developer': { clientId: string }; - wordpress: { clientId: string; serverURL: string }; - }; + services: IServices; Gitlab_URL: string; CAS_enabled: boolean; CAS_login_url: string; @@ -90,12 +103,13 @@ interface ILoginServicesProps { theme: string; } -class LoginServices extends React.PureComponent { - private _animation: any; +interface ILoginServicesState { + collapsed: boolean; + servicesHeight: Animated.Value; +} - static defaultProps = { - separator: true - }; +class LoginServices extends React.PureComponent { + private _animation?: Animated.CompositeAnimation | void; state = { collapsed: true, @@ -194,7 +208,7 @@ class LoginServices extends React.PureComponent { this.openOAuth({ url: `${endpoint}${params}` }); }; - onPressCustomOAuth = (loginService: any) => { + onPressCustomOAuth = (loginService: IItemService) => { logEvent(events.ENTER_WITH_CUSTOM_OAUTH); const { server } = this.props; const { serverURL, authorizePath, clientId, scope, service } = loginService; @@ -207,7 +221,7 @@ class LoginServices extends React.PureComponent { this.openOAuth({ url }); }; - onPressSaml = (loginService: any) => { + onPressSaml = (loginService: IItemService) => { logEvent(events.ENTER_WITH_SAML); const { server } = this.props; const { clientConfig } = loginService; @@ -234,7 +248,6 @@ class LoginServices extends React.PureComponent { AppleAuthentication.AppleAuthenticationScope.EMAIL ] }); - // @ts-ignore await RocketChat.loginOAuthOrSso({ fullName, email, identityToken }); } catch { logEvent(events.ENTER_WITH_APPLE_F); @@ -243,7 +256,12 @@ class LoginServices extends React.PureComponent { getOAuthState = (loginStyle = LOGIN_STYPE_POPUP) => { const credentialToken = random(43); - let obj: any = { loginStyle, credentialToken, isCordova: true }; + let obj: { + loginStyle: string; + credentialToken: string; + isCordova: boolean; + redirectUrl?: string; + } = { loginStyle, credentialToken, isCordova: true }; if (loginStyle === LOGIN_STYPE_REDIRECT) { obj = { ...obj, @@ -263,12 +281,11 @@ class LoginServices extends React.PureComponent { if (this._animation) { this._animation.stop(); } - // @ts-ignore this._animation = Animated.timing(servicesHeight, { toValue: height, duration: 300, - // @ts-ignore - easing: Easing.easeOutCubic + easing: Easing.inOut(Easing.quad), + useNativeDriver: true }).start(); }; @@ -281,11 +298,11 @@ class LoginServices extends React.PureComponent { } else { this.transitionServicesTo(SERVICES_COLLAPSED_HEIGHT); } - this.setState((prevState: any) => ({ collapsed: !prevState.collapsed })); + this.setState((prevState: ILoginServicesState) => ({ collapsed: !prevState.collapsed })); }; getSocialOauthProvider = (name: string) => { - const oauthProviders: any = { + const oauthProviders: IOauthProvider = { facebook: this.onPressFacebook, github: this.onPressGithub, gitlab: this.onPressGitlab, @@ -324,7 +341,7 @@ class LoginServices extends React.PureComponent { return null; }; - renderItem = (service: IService) => { + renderItem = (service: IItemService) => { const { CAS_enabled, theme } = this.props; let { name } = service; name = name === 'meteor-developer' ? 'meteor' : name; @@ -401,26 +418,28 @@ class LoginServices extends React.PureComponent { if (length > 3 && separator) { return ( <> - {Object.values(services).map((service: any) => this.renderItem(service))} + + {Object.values(services).map((service: IItemService) => this.renderItem(service))} + {this.renderServicesSeparator()} ); } return ( <> - {Object.values(services).map((service: any) => this.renderItem(service))} + {Object.values(services).map((service: IItemService) => this.renderItem(service))} {this.renderServicesSeparator()} ); } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: IApplicationState) => ({ server: state.server.server, - Gitlab_URL: state.settings.API_Gitlab_URL, - CAS_enabled: state.settings.CAS_enabled, - CAS_login_url: state.settings.CAS_login_url, - services: state.login.services + Gitlab_URL: state.settings.API_Gitlab_URL as string, + CAS_enabled: state.settings.CAS_enabled as boolean, + CAS_login_url: state.settings.CAS_login_url as string, + services: state.login.services as IServices }); -export default connect(mapStateToProps)(withTheme(LoginServices)) as any; +export default connect(mapStateToProps)(withTheme(LoginServices)); diff --git a/app/definitions/ICredentials.ts b/app/definitions/ICredentials.ts index 17d03a8b23..e5f96f0a5c 100644 --- a/app/definitions/ICredentials.ts +++ b/app/definitions/ICredentials.ts @@ -1,3 +1,5 @@ +import { AppleAuthenticationFullName } from 'expo-apple-authentication'; + export interface ICredentials { resume?: string; user?: string; @@ -13,4 +15,7 @@ export interface ICredentials { login: ICredentials; code: string; }; + fullName?: AppleAuthenticationFullName | null; + email?: string | null; + identityToken?: string | null; } diff --git a/app/selectors/login.ts b/app/selectors/login.ts index 2b634d6abb..b4f483fb7e 100644 --- a/app/selectors/login.ts +++ b/app/selectors/login.ts @@ -3,7 +3,7 @@ import isEmpty from 'lodash/isEmpty'; import { IApplicationState, IUser } from '../definitions'; -interface IServices { +export interface IServices { facebook: { clientId: string }; github: { clientId: string }; gitlab: { clientId: string }; diff --git a/app/stacks/types.ts b/app/stacks/types.ts index 278f1d55c0..ed4f161dd0 100644 --- a/app/stacks/types.ts +++ b/app/stacks/types.ts @@ -272,8 +272,14 @@ export type OutsideParamList = { }; RegisterView: { title: string; + username?: string; }; LegalView: undefined; + AuthenticationWebView: { + authType: string; + url: string; + ssoToken?: string; + }; }; export type OutsideModalParamList = { diff --git a/app/views/LoginView.tsx b/app/views/LoginView.tsx index a8bcba275a..d5b136dd5f 100644 --- a/app/views/LoginView.tsx +++ b/app/views/LoginView.tsx @@ -231,7 +231,7 @@ class LoginView extends React.Component { return ( - + {this.renderUserForm()} diff --git a/app/views/RegisterView.tsx b/app/views/RegisterView.tsx index 9d2023fb44..478198a1b4 100644 --- a/app/views/RegisterView.tsx +++ b/app/views/RegisterView.tsx @@ -237,7 +237,7 @@ class RegisterView extends React.Component { return ( - + {I18n.t('Sign_Up')}