@live-change/session-service 0.9.209 → 0.9.213

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.
package/authenticator.js CHANGED
@@ -6,29 +6,60 @@ import { createHmac } from 'crypto'
6
6
  const config = definition.config
7
7
 
8
8
  definition.authenticator({
9
+ name: 'session',
9
10
  async prepareCredentials(credentials) {
11
+ const startedAt = Date.now()
10
12
  const sessionKey = credentials.sessionKey
11
- if(!sessionKey) throw new Error("sessionKey required!")
12
- const sessions = await app.dao.get(
13
- ['database', 'indexRange', app.databaseName, Session.tableName + '_byKey', {
14
- gt: `"${sessionKey}"_`,
15
- lt: `"${sessionKey}"_\xFF`
16
- }])
17
- //console.log("FOUND SESSIONS", sessions)
18
- let session = sessions[0]?.to
19
- if(!session) {
20
- if(config.createSessionOnUpdate) {
21
- session = createHmac('sha256', config.sessionHmacSecret || 'secret')
22
- .update(credentials.sessionKey)
23
- .digest('base64').slice(0, 32).replace(/\//g, '_').replace(/\+/g, '-')
24
- } else {
25
- const createResult = await app.triggerService({ service: definition.name, type: "createSessionKeyIfNotExists" }, {
26
- sessionKey
13
+ const sessionKeyPrefix = sessionKey && typeof sessionKey === 'string'
14
+ ? sessionKey.slice(0, 8) + '…'
15
+ : undefined
16
+ let session = null
17
+ let path = null
18
+ try {
19
+ if(!config.createSessionOnUpdate) {
20
+ if(!sessionKey) throw new Error("sessionKey required!")
21
+ const sessions = await app.dao.get(
22
+ ['database', 'indexRange', app.databaseName, Session.tableName + '_byKey', {
23
+ gt: `"${sessionKey}"_`,
24
+ lt: `"${sessionKey}"_\xFF`
25
+ }])
26
+ //console.log("FOUND SESSIONS", sessions)
27
+ session = sessions[0]?.to
28
+ path = session ? 'lookup' : null
29
+ }
30
+ if(!session) {
31
+ if(config.createSessionOnUpdate) {
32
+ session = createHmac('sha256', config.sessionHmacSecret || 'secret')
33
+ .update(credentials.sessionKey)
34
+ .digest('base64').slice(0, 32).replace(/\//g, '_').replace(/\+/g, '-')
35
+ path = 'hmac'
36
+ } else {
37
+ const createResult = await app.triggerService({ service: definition.name, type: "createSessionKeyIfNotExists" }, {
38
+ sessionKey
39
+ })
40
+ //console.log("CREATE SESSION RESULT", createResult)
41
+ session = createResult.session
42
+ path = 'create'
43
+ }
44
+ }
45
+ credentials.session = session
46
+ const ms = Date.now() - startedAt
47
+ if(ms > 200 || process.env.DEBUG_AUTH === '1' || process.env.DEBUG_AUTH === 'true') {
48
+ console.log('[auth] prepareCredentials session done', {
49
+ sessionKeyPrefix,
50
+ session,
51
+ ms,
52
+ path
27
53
  })
28
- //console.log("CREATE SESSION RESULT", createResult)
29
- session = createResult.session
30
54
  }
55
+ } catch(error) {
56
+ console.error('[auth] prepareCredentials session error', {
57
+ sessionKeyPrefix,
58
+ ms: Date.now() - startedAt,
59
+ path,
60
+ error
61
+ })
62
+ throw error
31
63
  }
32
- credentials.session = session
33
64
  }
34
65
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/session-service",
3
- "version": "0.9.209",
3
+ "version": "0.9.213",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,9 +22,9 @@
22
22
  },
23
23
  "type": "module",
24
24
  "dependencies": {
25
- "@live-change/framework": "^0.9.209",
26
- "@live-change/relations-plugin": "^0.9.209",
25
+ "@live-change/framework": "^0.9.213",
26
+ "@live-change/relations-plugin": "^0.9.213",
27
27
  "pluralize": "^8.0.0"
28
28
  },
29
- "gitHead": "e1f934934d5d8a119f7ed27aa97bc6b9e9791719"
29
+ "gitHead": "1e22d761822df56c327242bccb3d7aed57631146"
30
30
  }
package/sessionItem.js CHANGED
@@ -3,6 +3,7 @@ import App from '@live-change/framework'
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
5
5
  } from '@live-change/framework'
6
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
6
7
  import { Session } from "./model.js"
7
8
 
8
9
  import pluralize from 'pluralize'
@@ -24,6 +25,7 @@ definition.processor(function(service, app) {
24
25
 
25
26
  const config = model.sessionItem
26
27
  const writeableProperties = modelProperties || config.writableProperties
28
+ const objectType = service.name + '_' + modelName
27
29
 
28
30
  console.log("SESSION ITEM", model)
29
31
 
@@ -97,7 +99,7 @@ definition.processor(function(service, app) {
97
99
  },
98
100
  //queuedBy: (command) => command.client.session,
99
101
  waitForEvents: true,
100
- async execute(properties, { client, service }, emit) {
102
+ async execute(properties, { client, service, trigger }, emit) {
101
103
  const id = properties[modelPropertyName] || app.generateUid()
102
104
  const entity = await modelRuntime().get(id)
103
105
  if(entity) throw app.logicError("exists")
@@ -110,6 +112,11 @@ definition.processor(function(service, app) {
110
112
  const data = App.utils.mergeDeep({},
111
113
  App.computeDefaults(model, properties, { client, service }), newObject)
112
114
  await App.validation.validate(data, validators, validationContext)
115
+ const identifiers = { session: client.session }
116
+ await fireChangeTriggers({
117
+ service, modelName, app, objectType, object: id,
118
+ identifiers, oldData: null, data, trigger
119
+ })
113
120
  emit({
114
121
  type: eventName,
115
122
  [modelPropertyName]: id,
@@ -141,7 +148,7 @@ definition.processor(function(service, app) {
141
148
  skipValidation: true,
142
149
  queuedBy: (command) => command.client.session,
143
150
  waitForEvents: true,
144
- async execute(properties, { client, service }, emit) {
151
+ async execute(properties, { client, service, trigger }, emit) {
145
152
  const entity = await modelRuntime().get(properties[modelPropertyName])
146
153
  if(!entity) throw app.logicError("not_found")
147
154
  if(entity.session != client.session) throw app.logicError("not_authorized")
@@ -155,6 +162,14 @@ definition.processor(function(service, app) {
155
162
  const data = App.utils.mergeDeep({}, updateObject, computedUpdates)
156
163
  const merged = App.utils.mergeDeep({}, entity, data)
157
164
  await App.validation.validate({ ...merged, [modelPropertyName]: entity.id }, validators, validationContext)
165
+ const identifiers = { session: client.session }
166
+ await fireChangeTriggers({
167
+ service, modelName, app, objectType, object: entity.id,
168
+ identifiers,
169
+ oldData: extractObjectData(writeableProperties, entity, {}),
170
+ data,
171
+ trigger
172
+ })
158
173
  emit({
159
174
  type: eventName,
160
175
  [modelPropertyName]: entity.id,
@@ -183,10 +198,18 @@ definition.processor(function(service, app) {
183
198
  },
184
199
  queuedBy: (command) => command.client.session,
185
200
  waitForEvents: true,
186
- async execute(properties, { client, service }, emit) {
201
+ async execute(properties, { client, service, trigger }, emit) {
187
202
  const entity = await modelRuntime().get(properties[modelPropertyName])
188
203
  if(!entity) throw app.logicError("not_found")
189
204
  if(entity.session != client.session) throw app.logicError("not_authorized")
205
+ const identifiers = { session: client.session }
206
+ await fireChangeTriggers({
207
+ service, modelName, app, objectType, object: entity.id,
208
+ identifiers,
209
+ oldData: extractObjectData(writeableProperties, entity, {}),
210
+ data: null,
211
+ trigger
212
+ })
190
213
  emit({
191
214
  type: eventName,
192
215
  [modelPropertyName]: entity.id,
@@ -1,6 +1,7 @@
1
1
  import definition from './definition.js'
2
2
  import App from '@live-change/framework'
3
3
  const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
4
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
4
5
  import { Session } from "./model.js"
5
6
 
6
7
  definition.processor(function(service, app) {
@@ -21,6 +22,7 @@ definition.processor(function(service, app) {
21
22
 
22
23
  const config = model.sessionProperty
23
24
  const writeableProperties = modelProperties || config.writableProperties
25
+ const objectType = service.name + '_' + modelName
24
26
 
25
27
  if(model.propertyOf) throw new Error("model " + modelName + " already have owner")
26
28
  model.propertyOf = {
@@ -69,7 +71,7 @@ definition.processor(function(service, app) {
69
71
  skipValidation: true,
70
72
  queuedBy: (command) => command.client.session,
71
73
  waitForEvents: true,
72
- async execute(properties, {client, service}, emit) {
74
+ async execute(properties, { client, service, trigger }, emit) {
73
75
  let newObject = {}
74
76
  for(const propertyName of writeableProperties) {
75
77
  if(properties.hasOwnProperty(propertyName)) {
@@ -79,6 +81,12 @@ definition.processor(function(service, app) {
79
81
  const data = App.utils.mergeDeep({},
80
82
  App.computeDefaults(model, properties, { client, service } ), newObject)
81
83
  await App.validation.validate(data, validators, validationContext)
84
+ const id = client.session
85
+ const identifiers = { session: client.session }
86
+ await fireChangeTriggers({
87
+ service, modelName, app, objectType, object: id,
88
+ identifiers, oldData: null, data, trigger
89
+ })
82
90
  emit({
83
91
  type: eventName,
84
92
  identifiers: {
@@ -105,7 +113,7 @@ definition.processor(function(service, app) {
105
113
  skipValidation: true,
106
114
  queuedBy: (command) => command.client.session,
107
115
  waitForEvents: true,
108
- async execute(properties, { client, service }, emit) {
116
+ async execute(properties, { client, service, trigger }, emit) {
109
117
  const entity = await modelRuntime().get(client.session)
110
118
  if(!entity) throw app.logicError("not_found")
111
119
  let updateObject = {}
@@ -119,6 +127,15 @@ definition.processor(function(service, app) {
119
127
  const merged = App.utils.mergeDeep({}, entity, data)
120
128
  await App.validation.validate({ session: client.session, ...merged }, validators,
121
129
  validationContext)
130
+ const id = client.session
131
+ const identifiers = { session: client.session }
132
+ await fireChangeTriggers({
133
+ service, modelName, app, objectType, object: id,
134
+ identifiers,
135
+ oldData: extractObjectData(writeableProperties, entity, {}),
136
+ data,
137
+ trigger
138
+ })
122
139
  emit({
123
140
  type: eventName,
124
141
  identifiers: {
@@ -141,9 +158,18 @@ definition.processor(function(service, app) {
141
158
  access: config.sessionResetAccess || config.sessionWriteAccess,
142
159
  queuedBy: (command) => command.client.session,
143
160
  waitForEvents: true,
144
- async execute(properties, {client, service}, emit) {
161
+ async execute(properties, { client, service, trigger }, emit) {
145
162
  const entity = await modelRuntime().indexObjectGet('bySession', client.session)
146
163
  if (!entity) throw app.logicError("not_found")
164
+ const id = client.session
165
+ const identifiers = { session: client.session }
166
+ await fireChangeTriggers({
167
+ service, modelName, app, objectType, object: id,
168
+ identifiers,
169
+ oldData: extractObjectData(writeableProperties, entity, {}),
170
+ data: null,
171
+ trigger
172
+ })
147
173
  emit({
148
174
  type: eventName,
149
175
  identifiers: {