diff --git a/packages/shared-components/src/api/mappers/user.ts b/packages/shared-components/src/api/mappers/user.ts index c043bb8c..8598462f 100644 --- a/packages/shared-components/src/api/mappers/user.ts +++ b/packages/shared-components/src/api/mappers/user.ts @@ -1,7 +1,8 @@ +import { GitHubUser } from 'shared-core/dist/types' import { User } from 'shared-core/dist/types/graphql' // TODO: Put this on a shared repository with the server -export function fromGitHubUser(user: any): User | null { +export function fromGitHubUser(user: GitHubUser): User['github'] | null { if (!(user && user.id)) return null return { diff --git a/packages/shared-components/src/components/cards/partials/NotificationCardHeader.tsx b/packages/shared-components/src/components/cards/partials/NotificationCardHeader.tsx index 70ccaa98..8d909d3f 100644 --- a/packages/shared-components/src/components/cards/partials/NotificationCardHeader.tsx +++ b/packages/shared-components/src/components/cards/partials/NotificationCardHeader.tsx @@ -51,7 +51,7 @@ const connectToStore = connect((state: any) => { const user = selectors.currentUserSelector(state) return { - username: (user && user.login) || '', + username: (user && user.github && user.github.login) || '', } }) diff --git a/packages/shared-components/src/components/columns/ColumnHeaderItem.tsx b/packages/shared-components/src/components/columns/ColumnHeaderItem.tsx index f0463da3..bdfebf0d 100644 --- a/packages/shared-components/src/components/columns/ColumnHeaderItem.tsx +++ b/packages/shared-components/src/components/columns/ColumnHeaderItem.tsx @@ -69,13 +69,9 @@ const styles = StyleSheet.create({ }, }) -const connectToStore = connect((state: any) => { - const user = selectors.currentUserSelector(state) - - return { - username: (user && user.login) || '', - } -}) +const connectToStore = connect((state: any) => ({ + username: selectors.currentUsernameSelector(state), +})) class ColumnHeaderItemComponent extends PureComponent< ColumnHeaderItemProps & ExtractPropsFromConnector diff --git a/packages/shared-components/src/components/layout/Sidebar.tsx b/packages/shared-components/src/components/layout/Sidebar.tsx index f1ab2eee..8285c301 100644 --- a/packages/shared-components/src/components/layout/Sidebar.tsx +++ b/packages/shared-components/src/components/layout/Sidebar.tsx @@ -38,15 +38,11 @@ export interface SidebarProps { } const connectToStore = connect( - (state: any) => { - const user = selectors.currentUserSelector(state) - - return { - columnIds: selectors.columnIdsSelector(state), - currentOpenedModal: selectors.currentOpenedModal(state), - username: (user && user.login) || '', - } - }, + (state: any) => ({ + columnIds: selectors.columnIdsSelector(state), + currentOpenedModal: selectors.currentOpenedModal(state), + username: selectors.currentUsernameSelector(state), + }), { replaceModal: actions.replaceModal, }, diff --git a/packages/shared-components/src/components/modals/SettingsModal.tsx b/packages/shared-components/src/components/modals/SettingsModal.tsx index 9f8fa202..7c62014c 100644 --- a/packages/shared-components/src/components/modals/SettingsModal.tsx +++ b/packages/shared-components/src/components/modals/SettingsModal.tsx @@ -19,10 +19,8 @@ export interface SettingsModalProps {} export function SettingsModal() { const { theme } = useContext(ThemeContext) - const user = useReduxState(selectors.currentUserSelector) const logout = useReduxAction(actions.logout) - - const username = (user && user.login) || '' + const username = useReduxState(selectors.currentUsernameSelector) return ( diff --git a/packages/shared-components/src/redux/actions/auth.ts b/packages/shared-components/src/redux/actions/auth.ts index 812c52b7..3898f518 100644 --- a/packages/shared-components/src/redux/actions/auth.ts +++ b/packages/shared-components/src/redux/actions/auth.ts @@ -19,7 +19,7 @@ export function loginSuccess(payload: { return createAction('LOGIN_SUCCESS', payload) } -export function loginFailure(error: { code: number; message: string }) { +export function loginFailure(error: any) { return createErrorAction('LOGIN_FAILURE', error) } diff --git a/packages/shared-components/src/redux/sagas/auth.ts b/packages/shared-components/src/redux/sagas/auth.ts index eac92caf..13e6e5f0 100644 --- a/packages/shared-components/src/redux/sagas/auth.ts +++ b/packages/shared-components/src/redux/sagas/auth.ts @@ -44,21 +44,26 @@ function* onLoginRequest( appToken githubToken user { - id - nodeId - login - name - avatarUrl - type - bio - publicGistsCount - publicReposCount - privateReposCount - privateGistsCount - followersCount - followingCount - ownedPrivateReposCount - isTwoFactorAuthenticationEnabled + _id + github { + id + nodeId + login + name + avatarUrl + type + bio + publicGistsCount + publicReposCount + privateReposCount + privateGistsCount + followersCount + followingCount + ownedPrivateReposCount + isTwoFactorAuthenticationEnabled + createdAt + updatedAt + } createdAt updatedAt } @@ -85,7 +90,9 @@ function* onLoginRequest( data.login.appToken && data.login.githubToken && data.login.user && - data.login.user.id + data.login.user._id && + data.login.user.github && + data.login.user.github.id ) ) { throw new Error('Invalid response') @@ -124,7 +131,7 @@ function* onLoginRequest( actions.loginSuccess({ appToken: action.payload.appToken, githubToken: action.payload.githubToken, - user, + user: { _id: '', github: user, createdAt: '', updatedAt: '' }, }), ) } catch (error) { @@ -141,7 +148,20 @@ function onLoginSuccess( function* onLoginFailure( action: ExtractActionFromActionCreator, ) { - if (action.error.code === 401) yield put(actions.logout()) + if ( + action.error && + (action.error.code === 401 || + (action.error.response && + (action.error.response.status === 401 || + (action.error.response.data && + Array.isArray(action.error.response.data.errors) && + action.error.response.data.errors.some( + (e: any) => + e.extensions && e.extensions.code === 'UNAUTHENTICATED', + ))))) + ) { + yield put(actions.logout()) + } } function onLogout() { diff --git a/packages/shared-components/src/redux/sagas/columns.ts b/packages/shared-components/src/redux/sagas/columns.ts index 67c34b80..aa954587 100644 --- a/packages/shared-components/src/redux/sagas/columns.ts +++ b/packages/shared-components/src/redux/sagas/columns.ts @@ -70,7 +70,7 @@ function getDefaultColumns(username: string): ColumnAndSubscriptions[] { function* onLoginSuccess( action: ExtractActionFromActionCreator, ) { - const username = action.payload.user.login + const username = action.payload.user.github.login const hasCreatedColumn = yield select(selectors.hasCreatedColumnSelector) if (!hasCreatedColumn) yield put(actions.replaceColumns(getDefaultColumns(username))) diff --git a/packages/shared-components/src/redux/selectors/auth.ts b/packages/shared-components/src/redux/selectors/auth.ts index 78d49d54..e7472a95 100644 --- a/packages/shared-components/src/redux/selectors/auth.ts +++ b/packages/shared-components/src/redux/selectors/auth.ts @@ -14,3 +14,8 @@ export const currentUserSelector = (state: RootState) => appTokenSelector(state) && githubTokenSelector(state) ? s(state).user : undefined + +export const currentUsernameSelector = (state: RootState) => { + const user = currentUserSelector(state) + return (user && user.github && user.github.login) || undefined +} diff --git a/packages/shared-core/src/types/github.ts b/packages/shared-core/src/types/github.ts index 578dee37..c4f4b926 100644 --- a/packages/shared-core/src/types/github.ts +++ b/packages/shared-core/src/types/github.ts @@ -19,14 +19,41 @@ export type GitHubExtractParamsFromActivityMethod = F extends ( : never export interface GitHubUser { - id: number | string - avatar_url: string // https://avatars.githubusercontent.com/u/2118189? + id: string | number + node_id?: string display_login?: string - gravatar_id: string login: string name: string - url: string // https://api.github.com/users/brunolemos - html_url?: string // https://github.com/brunolemos + avatar_url: string + gravatar_id: string + type: 'User' + site_admin: boolean + company?: string + blog?: string + location?: string + email?: string + hireable?: boolean + bio?: string + public_gists?: number + public_repos?: number + total_private_repos?: number + private_gists?: number + followers?: number + following?: number + owned_private_repos?: number + disk_usage?: number + collaborators?: number + two_factor_authentication: boolean + plan: { + name: string + space: number + collaborators: number + private_repos: number + } + url: string + html_url?: string + created_at: string + updated_at: string } export interface GitHubReaction { diff --git a/packages/shared-core/src/types/graphql.ts b/packages/shared-core/src/types/graphql.ts index 64c6e497..e66fe914 100644 --- a/packages/shared-core/src/types/graphql.ts +++ b/packages/shared-core/src/types/graphql.ts @@ -1,6 +1,6 @@ // TODO: Auto generate this from the schema using apollo codegen cli -export interface User { +export interface GraphQLGitHubUser { id: string nodeId: string login: string @@ -30,6 +30,13 @@ export interface User { updatedAt: string } +export interface User { + _id: string + github: GraphQLGitHubUser + createdAt: string + updatedAt: string +} + export interface GitHubPlan { name: string space?: number