RefreshToken support and matrix fixes
Also, some initial TypeScript.
This commit is contained in:
parent
f8f6c2ed94
commit
a6d932ddb5
8 changed files with 169 additions and 120 deletions
|
|
@ -90,17 +90,17 @@
|
|||
|
||||
<interactive-auth ref="interactiveAuth" />
|
||||
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" size="large"
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.getMyMembership() == 'ban')" size="large"
|
||||
@click.stop="handleJoin" :loading="loading" v-if="!currentUser">{{
|
||||
roomId && roomId.startsWith("@") ? $t("join.enter_room_user") : $t("join.enter_room")
|
||||
}}</v-btn>
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" size="large"
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.getMyMembership() == 'ban')" size="large"
|
||||
block @click.stop="handleJoin" :loading="loading" v-else>{{
|
||||
roomId && roomId.startsWith("@") ? $t("join.join_user") : $t("join.join")
|
||||
}}</v-btn>
|
||||
|
||||
<div v-if="loadingMessage" class="text-center">{{ loadingMessage }}</div>
|
||||
<div v-if="room && room.selfMembership == 'ban'" class="text-center">{{ $t("join.you_have_been_banned") }}</div>
|
||||
<div v-if="room && room.getMyMembership() == 'ban'" class="text-center">{{ $t("join.you_have_been_banned") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
export default class User {
|
||||
constructor(user_id, password, is_guest) {
|
||||
this.user_id = user_id;
|
||||
this.password = password;
|
||||
this.is_guest = is_guest || false
|
||||
}
|
||||
|
||||
static localPart(user_id) {
|
||||
if (user_id && user_id.startsWith('@') && user_id.includes(':')) {
|
||||
const parts = user_id.split(":");
|
||||
return parts[0].substring(1);
|
||||
}
|
||||
return user_id;
|
||||
}
|
||||
|
||||
static domainPart(user_id) {
|
||||
if (user_id && user_id.startsWith('@') && user_id.includes(':')) {
|
||||
const parts = user_id.split(":");
|
||||
return parts[1];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
27
src/models/user.ts
Normal file
27
src/models/user.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
export default class User {
|
||||
user_id: string;
|
||||
password: string | null;
|
||||
is_guest: boolean;
|
||||
|
||||
constructor(user_id: string, password: string | null, is_guest?: boolean) {
|
||||
this.user_id = user_id;
|
||||
this.password = password;
|
||||
this.is_guest = is_guest || false;
|
||||
}
|
||||
|
||||
static localPart(user_id: string | null) {
|
||||
if (user_id && user_id.startsWith("@") && user_id.includes(":")) {
|
||||
const parts = user_id.split(":");
|
||||
return parts[0].substring(1);
|
||||
}
|
||||
return user_id;
|
||||
}
|
||||
|
||||
static domainPart(user_id: string | null) {
|
||||
if (user_id && user_id.startsWith("@") && user_id.includes(":")) {
|
||||
const parts = user_id.split(":");
|
||||
return parts[1];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,23 @@
|
|||
import cleaninsights from "./cleaninsights.service";
|
||||
import matomo from "./matomo.service";
|
||||
|
||||
export interface AnalyticsEngine {
|
||||
event(category: string, action: string);
|
||||
}
|
||||
|
||||
type AnalyticsEvent = {
|
||||
category: string;
|
||||
action: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
install(app) {
|
||||
class AnalyticsServiceClass {
|
||||
|
||||
engines: AnalyticsEngine[];
|
||||
cachedEvents: AnalyticsEvent[];
|
||||
initialized: boolean;
|
||||
|
||||
constructor() {
|
||||
this.engines = [];
|
||||
this.cachedEvents = [];
|
||||
|
|
@ -37,7 +51,7 @@ export default {
|
|||
this.initialized = true;
|
||||
|
||||
// Handle cached events
|
||||
this.cachedEvents.forEach(([category, action]) => {
|
||||
this.cachedEvents.forEach(({category, action}) => {
|
||||
this.event(category, action);
|
||||
});
|
||||
this.cachedEvents = [];
|
||||
|
|
@ -46,7 +60,7 @@ export default {
|
|||
|
||||
event(category, action) {
|
||||
if (!this.initialized) {
|
||||
this.cachedEvents.push([category, action]);
|
||||
this.cachedEvents.push({category, action});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -85,19 +85,19 @@ export default {
|
|||
|
||||
joinedRooms() {
|
||||
return this.rooms.filter((room) => {
|
||||
return room.selfMembership === "join";
|
||||
return room.getMyMembership() === "join";
|
||||
});
|
||||
},
|
||||
|
||||
invites() {
|
||||
return this.rooms.filter((room) => {
|
||||
return room.selfMembership === "invite";
|
||||
return room.getMyMembership() === "invite";
|
||||
});
|
||||
},
|
||||
|
||||
joinedAndInvitedRooms() {
|
||||
return this.rooms.filter((room) => {
|
||||
return room.selfMembership === "join" || room.selfMembership === "invite";
|
||||
return room.getMyMembership() === "join" || room.getMyMembership() === "invite";
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
@ -313,6 +313,8 @@ export default {
|
|||
store: matrixStore,
|
||||
deviceId: user.device_id,
|
||||
accessToken: user.access_token,
|
||||
refreshToken: user.refresh_token,
|
||||
tokenRefreshFunction: this.onSessionRefresh,
|
||||
timelineSupport: true,
|
||||
unstableClientRelationAggregation: true,
|
||||
cryptoStore: cryptoStore
|
||||
|
|
@ -413,7 +415,7 @@ export default {
|
|||
case "m.room.join_rules":
|
||||
{
|
||||
const room = this.matrixClient.getRoom(event.getRoomId());
|
||||
if (room && room.getJoinRule() == "private" && room.selfMembership == "invite") {
|
||||
if (room && room.getJoinRule() == "private" && room.getMyMembership() == "invite") {
|
||||
// We have an invite to a room that's now "private"? This is most probably a deleted DM room.
|
||||
// Reject the invite, i.e. call "leave" on it.
|
||||
this.matrixClient.leave(room.roomId);
|
||||
|
|
@ -451,7 +453,7 @@ export default {
|
|||
},
|
||||
|
||||
onRoom(room) {
|
||||
if (room.selfMembership === "invite") {
|
||||
if (room.getMyMembership() === "invite") {
|
||||
this.matrixClient
|
||||
.getRoomTags(room.roomId)
|
||||
.then((reply) => {
|
||||
|
|
@ -468,7 +470,7 @@ export default {
|
|||
},
|
||||
|
||||
onRoomMyMembership(room) {
|
||||
if (room.selfMembership === "invite") {
|
||||
if (room.getMyMembership() === "invite") {
|
||||
// Invitation. Need to call "recalculate" to pick
|
||||
// up room name, not sure why exactly.
|
||||
room.recalculate();
|
||||
|
|
@ -476,6 +478,28 @@ export default {
|
|||
this.reloadRooms();
|
||||
},
|
||||
|
||||
onSessionRefresh(refreshToken) {
|
||||
const now = Date.now();
|
||||
return this.matrixClient.refreshToken(refreshToken).then((result) => {
|
||||
// Store new one!
|
||||
var user = this.$store.state.auth.user;
|
||||
user.access_token = result.access_token;
|
||||
user.refresh_token = result.refresh_token;
|
||||
user.expires_in_ms = result.expires_in_ms;
|
||||
this.$store.commit("setUser", user);
|
||||
|
||||
// Return AccessTokens struct
|
||||
let accesssTokens = {
|
||||
accessToken: result.access_token,
|
||||
refreshToken: result.refresh_token
|
||||
};
|
||||
if (result.expires_in_ms) {
|
||||
accesssTokens.expiry = new Date(now + result.expires_in_ms);
|
||||
};
|
||||
return accesssTokens;
|
||||
});
|
||||
},
|
||||
|
||||
onSessionLoggedOut() {
|
||||
console.log("Logged out!");
|
||||
if (this.matrixClient) {
|
||||
|
|
@ -517,7 +541,7 @@ export default {
|
|||
// each time!
|
||||
var updatedRooms = this.matrixClient.getVisibleRooms();
|
||||
updatedRooms = updatedRooms.filter((room) => {
|
||||
return room.selfMembership && (room.selfMembership == "invite" || room.selfMembership == "join") && room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETED).length == 0;
|
||||
return room.getMyMembership() && (room.getMyMembership() == "invite" || room.getMyMembership() == "join") && room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETED).length == 0;
|
||||
});
|
||||
updatedRooms.forEach((room) => {
|
||||
room["avatar"] = room.getAvatarUrl(this.matrixClient.getHomeserverUrl(), 80, 80, "scale", true, this.useAuthedMedia);
|
||||
|
|
@ -567,7 +591,7 @@ export default {
|
|||
var ids = {};
|
||||
const ret = [];
|
||||
for (const room of this.rooms) {
|
||||
if (room.selfMembership == "join" && this.getRoomJoinRule(room) == "invite") {
|
||||
if (room.getMyMembership() == "join" && this.getRoomJoinRule(room) == "invite") {
|
||||
for (const member of room.getJoinedMembers()) {
|
||||
if (member.userId != this.currentUserId && !ids[member.userId]) {
|
||||
ids[member.userId] = member;
|
||||
|
|
@ -842,7 +866,7 @@ export default {
|
|||
})
|
||||
.then(() => {
|
||||
//console.log("Purge: create timeline");
|
||||
return timelineWindow.load(null, 100);
|
||||
return timelineWindow.load(undefined, 100);
|
||||
})
|
||||
.then(() => {
|
||||
const getMoreIfAvailable = function _getMoreIfAvailable() {
|
||||
|
|
@ -1234,7 +1258,7 @@ export default {
|
|||
since: response.next_batch,
|
||||
})
|
||||
.then((response) => {
|
||||
return _findOrGetMore(client, response);
|
||||
return _findOrGetMore(client, useAuthedMedia, response);
|
||||
})
|
||||
.catch((err) => {
|
||||
return Promise.reject("Failed to find room: " + err);
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
export default {
|
||||
install(app, router) {
|
||||
var routes = [];
|
||||
var nextRoutes = null;
|
||||
var zeroIndex = undefined;
|
||||
|
||||
router.beforeResolve((to, ignoredfrom, next) => {
|
||||
if (!zeroIndex) {
|
||||
routes = [to];
|
||||
zeroIndex = window.history.length;
|
||||
}
|
||||
next();
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (nextRoutes) {
|
||||
console.log("Nav: next routes set, going:", routes, nextRoutes);
|
||||
routes = nextRoutes;
|
||||
nextRoutes = null;
|
||||
if (routes.length > 0) {
|
||||
console.log("Redirecting to", routes[routes.length - 1]);
|
||||
next(routes[routes.length - 1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
next();
|
||||
})
|
||||
|
||||
const navigationService = {
|
||||
/***
|
||||
* @param mode Mode of operation. -1 = push as root, 0 = replace, 1 = normal push
|
||||
*/
|
||||
push(route, mode) {
|
||||
if (mode === undefined) {
|
||||
mode = 1;
|
||||
}
|
||||
if (mode == -1) {
|
||||
nextRoutes = [route];
|
||||
} else if (mode == 0) {
|
||||
// Replace
|
||||
nextRoutes = [...routes];
|
||||
nextRoutes.pop();
|
||||
nextRoutes.push(route);
|
||||
} else {
|
||||
nextRoutes = [...routes];
|
||||
nextRoutes.push(route);
|
||||
}
|
||||
|
||||
const index = nextRoutes.length - routes.length;
|
||||
const targetIndex = nextRoutes.length - 1;
|
||||
console.log("Nav - index " + index + " Target " + targetIndex);
|
||||
if (index < 0) {
|
||||
console.log("Nav - go " + index);
|
||||
router.go(index);
|
||||
} else if (index == 0) {
|
||||
console.log("Nav - replace");
|
||||
routes = nextRoutes;
|
||||
nextRoutes = null;
|
||||
router.replace(route).catch((ignoredErr) => {});
|
||||
} else {
|
||||
console.log("Nav - push");
|
||||
router.push(route).catch((ignoredErr) => {});
|
||||
}
|
||||
},
|
||||
|
||||
canPop() {
|
||||
if (nextRoutes) {
|
||||
return nextRoutes.length > 1;
|
||||
}
|
||||
return routes.length > 1;
|
||||
},
|
||||
|
||||
pop() {
|
||||
routes.pop();
|
||||
router.go(-1);
|
||||
}
|
||||
}
|
||||
|
||||
app.$navigation = navigationService;
|
||||
app.config.globalProperties.$navigation = navigationService;
|
||||
}
|
||||
}
|
||||
84
src/services/navigation.service.ts
Normal file
84
src/services/navigation.service.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import { RouteLocationNormalizedGeneric, Router } from "vue-router";
|
||||
|
||||
export default {
|
||||
install(app, router: Router) {
|
||||
var routes: RouteLocationNormalizedGeneric[] = [];
|
||||
var nextRoutes: RouteLocationNormalizedGeneric[] | null = null;
|
||||
var zeroIndex: number | undefined = undefined;
|
||||
|
||||
router.beforeResolve((to, ignoredfrom, next) => {
|
||||
if (!zeroIndex) {
|
||||
routes = [to];
|
||||
zeroIndex = window.history.length;
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (nextRoutes) {
|
||||
console.log("Nav: next routes set, going:", routes, nextRoutes);
|
||||
routes = nextRoutes;
|
||||
nextRoutes = null;
|
||||
if (routes.length > 0) {
|
||||
console.log("Redirecting to", routes[routes.length - 1]);
|
||||
next(routes[routes.length - 1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
const navigationService = {
|
||||
/***
|
||||
* @param mode Mode of operation. -1 = push as root, 0 = replace, 1 = normal push
|
||||
*/
|
||||
push(route, mode) {
|
||||
if (mode === undefined) {
|
||||
mode = 1;
|
||||
}
|
||||
if (mode == -1) {
|
||||
nextRoutes = [route];
|
||||
} else if (mode == 0) {
|
||||
// Replace
|
||||
nextRoutes = [...routes];
|
||||
nextRoutes.pop();
|
||||
nextRoutes.push(route);
|
||||
} else {
|
||||
nextRoutes = [...routes];
|
||||
nextRoutes.push(route);
|
||||
}
|
||||
|
||||
const index = nextRoutes.length - routes.length;
|
||||
const targetIndex = nextRoutes.length - 1;
|
||||
console.log("Nav - index " + index + " Target " + targetIndex);
|
||||
if (index < 0) {
|
||||
console.log("Nav - go " + index);
|
||||
router.go(index);
|
||||
} else if (index == 0) {
|
||||
console.log("Nav - replace");
|
||||
routes = nextRoutes;
|
||||
nextRoutes = null;
|
||||
router.replace(route).catch((ignoredErr) => {});
|
||||
} else {
|
||||
console.log("Nav - push");
|
||||
router.push(route).catch((ignoredErr) => {});
|
||||
}
|
||||
},
|
||||
|
||||
canPop() {
|
||||
if (nextRoutes) {
|
||||
return nextRoutes.length > 1;
|
||||
}
|
||||
return routes.length > 1;
|
||||
},
|
||||
|
||||
pop() {
|
||||
routes.pop();
|
||||
router.go(-1);
|
||||
},
|
||||
};
|
||||
|
||||
app.$navigation = navigationService;
|
||||
app.config.globalProperties.$navigation = navigationService;
|
||||
},
|
||||
};
|
||||
5
tsconfig.json
Normal file
5
tsconfig.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"strict": true
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue