Skip to content

Commit

Permalink
Merge pull request #11752 from nextcloud/fix/noid/remove-access-token
Browse files Browse the repository at this point in the history
fix(federation): remove accessToken from project, migrate to typescript
  • Loading branch information
Antreesy authored Mar 8, 2024
2 parents 0b6d3f3 + d65669d commit 2fe9ad6
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 67 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --ext .js,.vue src --fix",
"lint": "eslint --ext .js,.ts,.vue src",
"lint:fix": "eslint --ext .js,.ts,.vue src --fix",
"stylelint": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue",
"stylelint:fix": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue --fix",
"analyze": "npm run analyze:stats && npm run analyze:serve",
Expand Down
2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import Router from './router/router.js'
import BrowserStorage from './services/BrowserStorage.js'
import { EventBus } from './services/EventBus.js'
import { leaveConversationSync } from './services/participantsService.js'
import { useFederationStore } from './stores/federation.js'
import { useFederationStore } from './stores/federation.ts'
import { checkBrowser } from './utils/browserCheck.js'
import { signalingKill } from './utils/webrtc/index.js'

Expand Down
2 changes: 1 addition & 1 deletion src/components/LeftSidebar/InvitationHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import ConversationIcon from '../ConversationIcon.vue'

import { CONVERSATION } from '../../constants.js'
import { useFederationStore } from '../../stores/federation.js'
import { useFederationStore } from '../../stores/federation.ts'

export default {
name: 'InvitationHandler',
Expand Down
2 changes: 1 addition & 1 deletion src/components/LeftSidebar/LeftSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ import {
} from '../../services/conversationsService.js'
import { EventBus } from '../../services/EventBus.js'
import { talkBroadcastChannel } from '../../services/talkBroadcastChannel.js'
import { useFederationStore } from '../../stores/federation.js'
import { useFederationStore } from '../../stores/federation.ts'
import { useTalkHashStore } from '../../stores/talkHash.js'
import CancelableRequest from '../../utils/cancelableRequest.js'
import { hasUnreadMentions, filterFunction } from '../../utils/conversation.js'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,34 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

import type { acceptShareResponse, getSharesResponse, rejectShareResponse } from '../types'

/**
* Fetches list of shares for a current user
*
* @param {object} [options] options;
* @param [options] options;
*/
const getShares = async function(options) {
const getShares = async function(options?: object): getSharesResponse {
return axios.get(generateOcsUrl('apps/spreed/api/v1/federation/invitation', undefined, options), options)
}

/**
* Accept an invitation by provided id.
*
* @param {number} id invitation id;
* @param {object} [options] options;
* @param id invitation id;
* @param [options] options;
*/
const acceptShare = async function(id, options) {
const acceptShare = async function(id: number, options?: object): acceptShareResponse {
return axios.post(generateOcsUrl('apps/spreed/api/v1/federation/invitation/{id}', { id }, options), {}, options)
}

/**
* Reject an invitation by provided id.
*
* @param {number} id invitation id;
* @param {object} [options] options;
* @param id invitation id;
* @param [options] options;
*/
const rejectShare = async function(id, options) {
const rejectShare = async function(id: number, options?: object): rejectShareResponse {
return axios.delete(generateOcsUrl('apps/spreed/api/v1/federation/invitation/{id}', { id }, options), options)
}

Expand Down
7 changes: 2 additions & 5 deletions src/stores/__tests__/federation.spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { setActivePinia, createPinia } from 'pinia'

import { getShares, acceptShare, rejectShare } from '../../services/federationService.js'
import { getShares, acceptShare, rejectShare } from '../../services/federationService.ts'
import { generateOCSErrorResponse, generateOCSResponse } from '../../test-helpers.js'
import { useFederationStore } from '../federation.js'
import { useFederationStore } from '../federation.ts'

jest.mock('../../services/federationService', () => ({
getShares: jest.fn(),
Expand All @@ -17,7 +17,6 @@ describe('federationStore', () => {
userId: 'user0',
state: 0,
localRoomId: 10,
accessToken: 'ACCESS_TOKEN',
remoteServerUrl: 'remote.nextcloud.com',
remoteToken: 'TOKEN_2',
remoteAttendeeId: 11,
Expand All @@ -30,7 +29,6 @@ describe('federationStore', () => {
userId: 'user0',
state: 1,
localRoomId: 9,
accessToken: 'ACCESS_TOKEN',
remoteServerUrl: 'remote.nextcloud.com',
remoteToken: 'TOKEN_1',
remoteAttendeeId: 11,
Expand Down Expand Up @@ -160,7 +158,6 @@ describe('federationStore', () => {

const room = {
id: 10,
remoteAccessToken: 'ACCESS_TOKEN',
}
const acceptResponse = generateOCSResponse({ payload: room })
acceptShare.mockResolvedValueOnce(acceptResponse)
Expand Down
65 changes: 21 additions & 44 deletions src/stores/federation.js → src/stores/federation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,25 @@ import { defineStore } from 'pinia'
import Vue from 'vue'

import { showError } from '@nextcloud/dialogs'
import { getBaseUrl } from '@nextcloud/router'

import { FEDERATION } from '../constants.js'
import { getShares, acceptShare, rejectShare } from '../services/federationService.js'
import { getShares, acceptShare, rejectShare } from '../services/federationService.ts'
import type { Conversation, FederationInvite, NotificationInvite } from '../types'

/**
* @typedef {object} Share
* @property {string} accessToken the invitation access token
* @property {number} id the invitation id
* @property {number} localRoomId the invitation local room id
* @property {number} remoteAttendeeId the invitation remote attendee id
* @property {string} remoteServerUrl the invitation remote server URL
* @property {string} remoteToken the invitation remote token
* @property {string} roomName the invitation room name
* @property {number} state the invitation state
* @property {string} userId the invitation user id
* @property {string} inviterCloudId the inviter cloud id
* @property {string} inviterDisplayName the inviter display name
*/

/**
* @typedef {object} State
* @property {{[key: string]: Share}} pendingShares - pending invitations
* @property {{[key: string]: Share}} acceptedShares - accepted invitations
*/

/**
* Store for other app integrations (additional actions for messages, participants, e.t.c)
*
* @param {string} id store name
* @param {State} options.state store state structure
*/
type State = {
pendingShares: Record<string, FederationInvite & { loading?: 'accept' | 'reject' }>,
acceptedShares: Record<string, FederationInvite>,
}
export const useFederationStore = defineStore('federation', {
state: () => ({
state: (): State => ({
pendingShares: {},
acceptedShares: {},
}),

actions: {
/**
* Fetch pending invitations and keep them in store
*
*/
async getShares() {
try {
Expand All @@ -84,19 +62,19 @@ export const useFederationStore = defineStore('federation', {
/**
* Add an invitation from notification to the store.
*
* @param {object} notification notification object
* @param notification notification object
*/
addInvitationFromNotification(notification) {
addInvitationFromNotification(notification: NotificationInvite) {
if (this.pendingShares[notification.objectId]) {
return
}
const [remoteServerUrl, remoteToken] = notification.messageRichParameters.roomName.id.split('::')
const { id, name } = notification.messageRichParameters.user1
const invitation = {
accessToken: null,
const invitation: FederationInvite = {
id: notification.objectId,
localRoomId: null,
remoteAttendeeId: null,
localRoomId: 0,
localCloudId: notification.user + '@' + getBaseUrl().replace('https://', ''),
remoteAttendeeId: 0,
remoteServerUrl,
remoteToken,
roomName: notification.messageRichParameters.roomName.name,
Expand All @@ -111,10 +89,10 @@ export const useFederationStore = defineStore('federation', {
/**
* Mark an invitation as accepted in store.
*
* @param {number} id invitation id
* @param {object} conversation conversation object
* @param id invitation id
* @param conversation conversation object
*/
markInvitationAccepted(id, conversation) {
markInvitationAccepted(id: number, conversation: Conversation) {
if (!this.pendingShares[id]) {
return
}
Expand All @@ -130,10 +108,9 @@ export const useFederationStore = defineStore('federation', {
/**
* Accept an invitation by provided id.
*
* @param {number} id invitation id
* @return {object} conversation to join
* @param id invitation id
*/
async acceptShare(id) {
async acceptShare(id: number): Promise<Conversation | undefined> {
if (!this.pendingShares[id]) {
return
}
Expand All @@ -151,9 +128,9 @@ export const useFederationStore = defineStore('federation', {
/**
* Reject an invitation by provided id.
*
* @param {number} id invitation id
* @param id invitation id
*/
async rejectShare(id) {
async rejectShare(id: number) {
if (!this.pendingShares[id]) {
return
}
Expand Down
46 changes: 43 additions & 3 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,42 @@ import type { components, operations } from './openapi/openapi-full.ts'
type ApiOptions<T> = { params: T }
type ApiResponse<T> = Promise<{ data: T }>

// Conversations
export type Conversation = components['schemas']['Room']
// Notifications
type NotificationAction = {
label: string,
link: string,
type: 'WEB' | 'POST' | 'DELETE' | string,
primary: boolean,
}

// Chats
type ParamObject = {
id: string,
name: string,
type: string,
}
export type Notification<T = Record<string, ParamObject & Record<string, unknown>>> = {
notificationId: number,
app: string,
user: string,
datetime: string,
objectType: string,
objectId: number,
subject: string,
message: string,
link: string,
subjectRich: string,
subjectRichParameters: T,
messageRich: string,
messageRichParameters: T,
icon: string,
shouldNotify: true,
actions: NotificationAction[],
}

// Conversations
export type Conversation = components['schemas']['Room']

// Chats
export type Mention = ParamObject & {
server?: string,
'call-type'?: string,
Expand Down Expand Up @@ -48,3 +75,16 @@ export type getBotsResponse = ApiResponse<operations['bot-list-bots']['responses
export type getBotsAdminResponse = ApiResponse<operations['settings-admin-list-bots']['responses'][200]['content']['application/json']>
export type enableBotResponse = ApiResponse<operations['bot-enable-bot']['responses'][201]['content']['application/json']>
export type disableBotResponse = ApiResponse<operations['bot-disable-bot']['responses'][200]['content']['application/json']>

// Federations
export type FederationInvite = components['schemas']['FederationInvite']
type FederationInviteRichParameters = {
user1: ParamObject & { server: string },
roomName: ParamObject,
remoteServer: ParamObject,
}
export type NotificationInvite = Notification<FederationInviteRichParameters>

export type getSharesResponse = ApiResponse<operations['federation-get-shares']['responses'][200]['content']['application/json']>
export type acceptShareResponse = ApiResponse<operations['federation-accept-share']['responses'][200]['content']['application/json']>
export type rejectShareResponse = ApiResponse<operations['federation-reject-share']['responses'][200]['content']['application/json']>
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"extends": "@vue/tsconfig/tsconfig.json",
"include": ["src/**/*.ts"],
"include": ["src/**/*.ts", "src/env.d.ts"],
"exclude": ["node_modules", "vendor"],
"compilerOptions": {
"outDir": "./js",
"allowJs": true,
"checkJs": true,
"checkJs": false,
"allowImportingTsExtensions": true,
"lib": ["ESNext"],
},
Expand Down

0 comments on commit 2fe9ad6

Please sign in to comment.