diff --git a/js/package.json b/js/package.json index 45be10602..3250a61dc 100644 --- a/js/package.json +++ b/js/package.json @@ -17,7 +17,6 @@ "apollo-client": "2.5.1", "apollo-link": "^1.2.11", "apollo-link-http": "^1.5.14", - "apollo-link-state": "^0.4.2", "buefy": "^0.7.3", "easygettext": "^2.7.0", "graphql": "^14.2.1", @@ -53,6 +52,7 @@ "@vue/cli-service": "^3.6.0", "@vue/eslint-config-typescript": "^4.0.0", "@vue/test-utils": "^1.0.0-beta.29", + "apollo-link-error": "^1.1.11", "chai": "^4.2.0", "dotenv-webpack": "^1.7.0", "eslint": "^6.0.1", diff --git a/js/src/App.vue b/js/src/App.vue index 183adb48c..2be5576e2 100644 --- a/js/src/App.vue +++ b/js/src/App.vue @@ -11,7 +11,7 @@ diff --git a/js/src/constants.ts b/js/src/constants.ts index 9ccb54d2b..79dbe270f 100644 --- a/js/src/constants.ts +++ b/js/src/constants.ts @@ -1,4 +1,5 @@ -export const AUTH_TOKEN = 'auth-token'; +export const AUTH_ACCESS_TOKEN = 'auth-access-token'; +export const AUTH_REFRESH_TOKEN = 'auth-refresh-token'; export const AUTH_USER_ID = 'auth-user-id'; export const AUTH_USER_EMAIL = 'auth-user-email'; export const AUTH_USER_ACTOR = 'auth-user-actor'; diff --git a/js/src/graphql/auth.ts b/js/src/graphql/auth.ts index 8b757ee59..e491a9c11 100644 --- a/js/src/graphql/auth.ts +++ b/js/src/graphql/auth.ts @@ -3,7 +3,8 @@ import gql from 'graphql-tag'; export const LOGIN = gql` mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { - token, + accessToken, + refreshToken, user { id, } @@ -33,3 +34,12 @@ mutation ResendConfirmationEmail($email: String!) { resendConfirmationEmail(email: $email) } `; + +export const REFRESH_TOKEN = gql` + mutation RefreshToken($refreshToken: String!) { + refreshToken(refreshToken: $refreshToken) { + accessToken, + refreshToken, + } + } +`; diff --git a/js/src/graphql/user.ts b/js/src/graphql/user.ts index 06c300404..b23b5da32 100644 --- a/js/src/graphql/user.ts +++ b/js/src/graphql/user.ts @@ -12,7 +12,8 @@ mutation CreateUser($email: String!, $password: String!) { export const VALIDATE_USER = gql` mutation ValidateUser($token: String!) { validateUser(token: $token) { - token, + accessToken, + refreshToken, user { id, email, diff --git a/js/src/router/guards/auth-guard.ts b/js/src/router/guards/auth-guard.ts index fb1c0c9ec..1f6bf82b4 100644 --- a/js/src/router/guards/auth-guard.ts +++ b/js/src/router/guards/auth-guard.ts @@ -1,13 +1,13 @@ import { NavigationGuard } from 'vue-router'; import { UserRouteName } from '@/router/user'; import { LoginErrorCode } from '@/types/login-error-code.model'; -import { AUTH_TOKEN } from '@/constants'; +import { AUTH_ACCESS_TOKEN } from '@/constants'; export const authGuardIfNeeded: NavigationGuard = async function (to, from, next) { if (to.meta.requiredAuth !== true) return next(); // We can't use "currentUser" from apollo here because we may not have loaded the user from the local storage yet - if (!localStorage.getItem(AUTH_TOKEN)) { + if (!localStorage.getItem(AUTH_ACCESS_TOKEN)) { return next({ name: UserRouteName.LOGIN, query: { diff --git a/js/src/types/apollo.ts b/js/src/types/apollo.ts new file mode 100644 index 000000000..a35cb8307 --- /dev/null +++ b/js/src/types/apollo.ts @@ -0,0 +1,7 @@ +import { ServerError, ServerParseError } from 'apollo-link-http-common'; + +function isServerError(err: Error | ServerError | ServerParseError | undefined): err is ServerError { + return !!err && (err as ServerError).statusCode !== undefined; +} + +export { isServerError }; diff --git a/js/src/types/login.model.ts b/js/src/types/login.model.ts index 73289a066..3807b150b 100644 --- a/js/src/types/login.model.ts +++ b/js/src/types/login.model.ts @@ -1,7 +1,10 @@ import { ICurrentUser } from '@/types/current-user.model'; -export interface ILogin { - user: ICurrentUser; - - token: string; +export interface IToken { + accessToken: string; + refreshToken: string; +} + +export interface ILogin extends IToken { + user: ICurrentUser; } diff --git a/js/src/utils/auth.ts b/js/src/utils/auth.ts index c2cb8010a..29698bf7a 100644 --- a/js/src/utils/auth.ts +++ b/js/src/utils/auth.ts @@ -1,14 +1,38 @@ -import { AUTH_TOKEN, AUTH_USER_EMAIL, AUTH_USER_ID } from '@/constants'; -import { ILogin } from '@/types/login.model'; +import { AUTH_ACCESS_TOKEN, AUTH_REFRESH_TOKEN, AUTH_USER_EMAIL, AUTH_USER_ID } from '@/constants'; +import { ILogin, IToken } from '@/types/login.model'; +import { UPDATE_CURRENT_USER_CLIENT } from '@/graphql/user'; +import { onLogout } from '@/vue-apollo'; +import ApolloClient from 'apollo-client'; export function saveUserData(obj: ILogin) { localStorage.setItem(AUTH_USER_ID, `${obj.user.id}`); localStorage.setItem(AUTH_USER_EMAIL, obj.user.email); - localStorage.setItem(AUTH_TOKEN, obj.token); + + saveTokenData(obj); +} + +export function saveTokenData(obj: IToken) { + localStorage.setItem(AUTH_ACCESS_TOKEN, obj.accessToken); + localStorage.setItem(AUTH_REFRESH_TOKEN, obj.refreshToken); } export function deleteUserData() { - for (const key of [AUTH_USER_ID, AUTH_USER_EMAIL, AUTH_TOKEN]) { + for (const key of [AUTH_USER_ID, AUTH_USER_EMAIL, AUTH_ACCESS_TOKEN, AUTH_REFRESH_TOKEN]) { localStorage.removeItem(key); } } + +export function logout(apollo: ApolloClient) { + apollo.mutate({ + mutation: UPDATE_CURRENT_USER_CLIENT, + variables: { + id: null, + email: null, + isLoggedIn: false, + }, + }); + + deleteUserData(); + + onLogout(); +} diff --git a/js/src/views/Event/Create.vue b/js/src/views/Event/Create.vue index 856432c05..0de44411e 100644 --- a/js/src/views/Event/Create.vue +++ b/js/src/views/Event/Create.vue @@ -137,9 +137,9 @@ export default class CreateEvent extends Vue { const obj = { organizerActorId: this.loggedPerson.id, beginsOn: this.event.beginsOn.toISOString(), - tags: this.event.tags.map((tag: ITag) => tag.title) + tags: this.event.tags.map((tag: ITag) => tag.title), }; - let res = Object.assign({}, this.event, obj); + const res = Object.assign({}, this.event, obj); if (this.event.physicalAddress) { delete this.event.physicalAddress['__typename']; diff --git a/js/src/views/Home.vue b/js/src/views/Home.vue index 77970c1c5..2185c2c44 100644 --- a/js/src/views/Home.vue +++ b/js/src/views/Home.vue @@ -1,5 +1,5 @@