@live-change/peer-connection-service 0.9.203 → 0.9.204

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Peer id format: channelType:channel:peerSession:instance
3
+ * The channel segment may contain ':' — only the first segment is channelType and
4
+ * the last two are peerSession and instance; everything between is the channel.
5
+ */
6
+ export function decodePeerId(peer) {
7
+ const parts = peer.split(':')
8
+ if (parts.length < 4) {
9
+ throw new Error(`invalid peer id: expected at least 4 colon-separated segments, got ${parts.length}`)
10
+ }
11
+ return {
12
+ channelType: parts[0],
13
+ channel: parts.slice(1, -2).join(':'),
14
+ peerSession: parts[parts.length - 2],
15
+ instance: parts[parts.length - 1]
16
+ }
17
+ }
package/index.js CHANGED
@@ -8,4 +8,5 @@ import './peer.js'
8
8
  import './peerState.js'
9
9
  import './message.js'
10
10
 
11
+ export { decodePeerId } from './decodePeerId.js'
11
12
  export default definition
package/message.js CHANGED
@@ -5,6 +5,7 @@ import accessControl from '@live-change/access-control-service/access.js'
5
5
  const { clientHasAccessRoles } = accessControl(definition)
6
6
 
7
7
  import { Peer } from './peer.js'
8
+ import { decodePeerId } from './decodePeerId.js'
8
9
 
9
10
  const messageFields = {
10
11
  to: {
@@ -91,8 +92,9 @@ definition.view({
91
92
  access: async({ peer }, { client, service, visibilityTest }) => {
92
93
  if(visibilityTest) return true
93
94
  if(!peer) throw new Error("peer parameter is required")
94
- console.log('MESSAGES ACCESS', peer.split(':'), "[2] == ", client.session)
95
- return peer.split(':')[2] === client.session
95
+ const { peerSession } = decodePeerId(peer)
96
+ console.log('MESSAGES ACCESS', { peerSession, clientSession: client.session })
97
+ return peerSession === client.session
96
98
  },
97
99
  async daoPath({ peer, gt, lt, gte, lte, limit, reverse }, { client, service }, method) {
98
100
  const channelId = peer
@@ -162,12 +164,12 @@ definition.action({
162
164
  access: async ({ from, to }, context) => {
163
165
  const { client, service, visibilityTest } = context
164
166
  if(visibilityTest) return true
165
- const [fromType, fromId, fromSession] = from.split(':')
166
- const [toType, toId, toSession] = to.split(':')
167
- //console.log("POST MESSAGE", fromType, fromId, fromSession, '=>', toType, toId, toSession, "BY", client)
168
- if(toType !== fromType || toId !== fromId) return false // different channel
169
- if(client.session !== fromSession) return false
170
- const hasRole = await clientHasAccessRoles(client, { objectType: toType, object: toId }, config.writerRoles)
167
+ const fromDecoded = decodePeerId(from)
168
+ const toDecoded = decodePeerId(to)
169
+ //console.log("POST MESSAGE", fromDecoded, '=>', toDecoded, "BY", client)
170
+ if(toDecoded.channelType !== fromDecoded.channelType || toDecoded.channel !== fromDecoded.channel) return false // different channel
171
+ if(client.session !== fromDecoded.peerSession) return false
172
+ const hasRole = await clientHasAccessRoles(client, { objectType: toDecoded.channelType, object: toDecoded.channel }, config.writerRoles)
171
173
  return hasRole
172
174
  },
173
175
  queuedBy: (props) => props.from+':'+props.to, // without this, messages order can be changed
@@ -203,12 +205,12 @@ definition.action({
203
205
  access: async ({ from, to }, context) => {
204
206
  const { client, service, visibilityTest } = context
205
207
  if(visibilityTest) return true
206
- const [fromType, fromId, fromSession] = from.split(':')
207
- const [toType, toId, toSession] = to.split(':')
208
- // console.log("POST MESSAGE", fromType, fromId, fromSession, '=>', toType, toId, toSession, "BY", client)
209
- if(toType !== fromType || toId !== fromId) return false // different channel
210
- if(client.session !== fromSession) return false
211
- const hasRole = await clientHasAccessRoles(client, { objectType: toType, object: toId }, config.writerRoles)
208
+ const fromDecoded = decodePeerId(from)
209
+ const toDecoded = decodePeerId(to)
210
+ // console.log("POST MESSAGE", fromDecoded, '=>', toDecoded, "BY", client)
211
+ if(toDecoded.channelType !== fromDecoded.channelType || toDecoded.channel !== fromDecoded.channel) return false // different channel
212
+ if(client.session !== fromDecoded.peerSession) return false
213
+ const hasRole = await clientHasAccessRoles(client, { objectType: toDecoded.channelType, object: toDecoded.channel }, config.writerRoles)
212
214
  return hasRole
213
215
  },
214
216
  queuedBy: (props) => props.from+':'+props.to, // without this, messages order can be changed
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@live-change/peer-connection-service",
3
- "version": "0.9.203",
3
+ "version": "0.9.204",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "start": "node index.js",
9
9
  "setup": "INSTALL=true node index.js",
10
- "test": "NODE_ENV=test blue-tape tests/*"
10
+ "test": "node --test tests/"
11
11
  },
12
12
  "author": "Michał Łaszczewski <michal@emikse.com>",
13
13
  "license": "BSD-3-Clause",
14
- "gitHead": "4d4ce413fe747da2c398eb4ad378e37cc81874b3"
14
+ "gitHead": "6ac17ccf3c184ca4d7ef920f63827dbfd8749f96"
15
15
  }
package/peer.js CHANGED
@@ -3,6 +3,7 @@ const app = App.app()
3
3
 
4
4
  import definition from './definition.js'
5
5
  import config from './config.js'
6
+ import { decodePeerId } from './decodePeerId.js'
6
7
 
7
8
  import accessControl from '@live-change/access-control-service/access.js'
8
9
  const { clientHasAccessRoles } = accessControl(definition)
@@ -40,8 +41,8 @@ definition.view({
40
41
  //console.log("CHECK PEERS ACCESS", params, client, visibilityTest)
41
42
  return clientHasAccessRoles(client, { objectType: channelType, object: channel }, config.readerRoles)
42
43
  },
43
- async daoPath({ channelType, channel }, { client, service }, method) {
44
- return Peer.indexRangePath('byChannel', [ channelType, channel.split(':')[0] ])
44
+ async daoPath({ channelType, channel }, { client, service }, method) {
45
+ return Peer.indexRangePath('byChannel', [ channelType, channel ])
45
46
  }
46
47
  })
47
48
 
@@ -80,7 +81,7 @@ definition.trigger({
80
81
  },
81
82
  async execute({ session, peer }, context, emit) {
82
83
  console.log("PEER ONLINE PARAMS", { session, peer })
83
- const [ channelType, channel, peerSession, instance ] = peer.split(':')
84
+ const { channelType, channel, peerSession, instance } = decodePeerId(peer)
84
85
  if(peerSession !== session) throw new Error('wrongSession')
85
86
  /// TODO: check channel access
86
87
  emit({
@@ -96,7 +97,7 @@ definition.trigger({
96
97
  },
97
98
  async execute({ session, peer }, context, emit) {
98
99
  console.log("PEER OFFLINE PARAMS", { session, peer })
99
- const [ channelType, channel, peerSession, instance ] = peer.split(':')
100
+ const { channelType, channel, peerSession, instance } = decodePeerId(peer)
100
101
  if(peerSession !== session) throw new Error('wrongSession')
101
102
  emit({
102
103
  type: 'peerOffline',
package/peerState.js CHANGED
@@ -5,6 +5,7 @@ import accessControl from '@live-change/access-control-service/access.js'
5
5
  const { clientHasAccessRoles } = accessControl(definition)
6
6
 
7
7
  import { Peer } from './peer.js'
8
+ import { decodePeerId } from './decodePeerId.js'
8
9
 
9
10
 
10
11
  const peerStateFields = {
@@ -55,7 +56,7 @@ definition.action({
55
56
  access: async ({ peer }, context) => {
56
57
  const { client, service, visibilityTest } = context
57
58
  if(visibilityTest) return true
58
- const [toType, toId, toSession] = peer.split(':')
59
+ const { channelType: toType, channel: toId, peerSession: toSession } = decodePeerId(peer)
59
60
  if(client.session !== toSession) return false
60
61
  const hasRole = await clientHasAccessRoles(client, { objectType: toType, object: toId }, config.writerRoles)
61
62
  return hasRole
@@ -0,0 +1,23 @@
1
+ import test from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { decodePeerId } from '../decodePeerId.js'
4
+
5
+ test('decodePeerId: four segments, channel without colon', () => {
6
+ const r = decodePeerId('room_Room:chanId:sessA:inst1')
7
+ assert.equal(r.channelType, 'room_Room')
8
+ assert.equal(r.channel, 'chanId')
9
+ assert.equal(r.peerSession, 'sessA')
10
+ assert.equal(r.instance, 'inst1')
11
+ })
12
+
13
+ test('decodePeerId: channel contains colons', () => {
14
+ const r = decodePeerId('t:a:b:c:d:e:f')
15
+ assert.equal(r.channelType, 't')
16
+ assert.equal(r.channel, 'a:b:c:d')
17
+ assert.equal(r.peerSession, 'e')
18
+ assert.equal(r.instance, 'f')
19
+ })
20
+
21
+ test('decodePeerId: rejects fewer than four segments', () => {
22
+ assert.throws(() => decodePeerId('a:b:c'), /invalid peer id/)
23
+ })
package/turn.js CHANGED
@@ -12,6 +12,7 @@ const { clientHasAccessRoles } = accessControl(definition)
12
12
 
13
13
 
14
14
  import { Peer } from './peer.js'
15
+ import { decodePeerId } from './decodePeerId.js'
15
16
 
16
17
  function randomHexString(size) {
17
18
  return new Promise((resolve, reject) => {
@@ -57,8 +58,8 @@ definition.view({
57
58
  },
58
59
  access: async ({ peer }, { client, service, visibilityTest }) => {
59
60
  if(visibilityTest) return true
60
- const [ channelType, channel, session, instance ] = peer.split(':')
61
- if(session !== client.session) throw new Error('wrongSession')
61
+ const { channelType, channel, peerSession } = decodePeerId(peer)
62
+ if(peerSession !== client.session) throw new Error('wrongSession')
62
63
  const result = await clientHasAccessRoles(client, { objectType: channelType.split('.')[0], object: channel },
63
64
  config.writerRoles)
64
65
  return result