@ossy/users 1.1.0
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/package.json +29 -0
- package/src/index.js +3 -0
- package/src/user.aggregate.js +84 -0
- package/src/users.events.js +121 -0
- package/src/users.validators.js +6 -0
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ossy/users",
|
|
3
|
+
"description": "User domain — aggregate, events, and validators for the Ossy user model",
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./src/index.js",
|
|
8
|
+
"module": "./src/index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
"author": "Ossy <yourfriends@ossy.se> (https://ossy.se)",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"ossy": {
|
|
15
|
+
"src": "./src"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"nanoid": "^5.1.11"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"/src",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"gitHead": "5f1feadf3b630aa96ec61f1d48c11e0e1aa4b095"
|
|
29
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
export class User {
|
|
3
|
+
|
|
4
|
+
static AggregateType = 'User'
|
|
5
|
+
|
|
6
|
+
static View(events, savedState = {}) {
|
|
7
|
+
return events.reduce((user, event) => {
|
|
8
|
+
|
|
9
|
+
switch (event.type) {
|
|
10
|
+
|
|
11
|
+
case 'SignedUp':
|
|
12
|
+
return {
|
|
13
|
+
...user,
|
|
14
|
+
id: event.aggregateId,
|
|
15
|
+
type: event.payload.type,
|
|
16
|
+
created: event.created,
|
|
17
|
+
email: event.payload.email,
|
|
18
|
+
verificationToken: event.payload.verificationToken,
|
|
19
|
+
firstName: event.payload.firstName,
|
|
20
|
+
lastName: event.payload.lastName,
|
|
21
|
+
workspaces: user.workspaces ?? []
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
case 'SignInVerified':
|
|
25
|
+
return {
|
|
26
|
+
...user,
|
|
27
|
+
verifiedAt: user.verifiedAt ?? event.created
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
case 'NameUpdated': {
|
|
31
|
+
const firstName = event.payload.firstName || user.firstName
|
|
32
|
+
const lastName = event.payload.lastName || user.lastName
|
|
33
|
+
return {
|
|
34
|
+
...user,
|
|
35
|
+
firstName,
|
|
36
|
+
lastName
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// TODO: #415
|
|
41
|
+
// case 'EmailUpdated':
|
|
42
|
+
// return {
|
|
43
|
+
// ...user,
|
|
44
|
+
// email: event.payload.email
|
|
45
|
+
// }
|
|
46
|
+
|
|
47
|
+
case 'WorkspaceJoined':
|
|
48
|
+
return {
|
|
49
|
+
...user,
|
|
50
|
+
workspaces: [...new Set([...(user.workspaces ?? []), event.payload.workspaceId])]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
case 'WorkspaceLeft':
|
|
54
|
+
return {
|
|
55
|
+
...user,
|
|
56
|
+
workspaces: (user.workspaces ?? []).filter(id => id !== event.payload.workspaceId)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
default:
|
|
60
|
+
return user
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
}, savedState)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static UserForWorkspace(events, aggregate) {
|
|
67
|
+
const user = User.View(events, aggregate)
|
|
68
|
+
return {
|
|
69
|
+
id: user.id,
|
|
70
|
+
firstName: user.firstName,
|
|
71
|
+
lastName: user.lastName,
|
|
72
|
+
email: user.email,
|
|
73
|
+
type: user.type
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static History(events) {
|
|
78
|
+
// TODO: add aggregate
|
|
79
|
+
return events
|
|
80
|
+
.sort((a, b) => b.created - a.created)
|
|
81
|
+
.map(event => ({ type: event.type, created: event.created }))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Database queries related to workspace events
|
|
5
|
+
* @class
|
|
6
|
+
*/
|
|
7
|
+
export class UsersEvents {
|
|
8
|
+
|
|
9
|
+
static SignedUp({
|
|
10
|
+
email,
|
|
11
|
+
lastName,
|
|
12
|
+
firstName,
|
|
13
|
+
userId: _userId,
|
|
14
|
+
type = 'User' // is 'User' or 'Bot'
|
|
15
|
+
}) {
|
|
16
|
+
const userId = _userId || nanoid()
|
|
17
|
+
return ({
|
|
18
|
+
type: 'SignedUp',
|
|
19
|
+
aggregateId: userId,
|
|
20
|
+
createdBy: userId,
|
|
21
|
+
payload: {
|
|
22
|
+
email: email,
|
|
23
|
+
lastName,
|
|
24
|
+
firstName,
|
|
25
|
+
type: type
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// static SignInRequested({ createdBy }) {
|
|
31
|
+
// return ({
|
|
32
|
+
// type: 'SignInRequested',
|
|
33
|
+
// createdBy: createdBy,
|
|
34
|
+
// payload: { verificationToken: TokenService.new() }
|
|
35
|
+
// })
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
/** Same JWT as the `auth` cookie / WebAuth token aggregate — see `UsersQueries.getIdByAuthToken`. */
|
|
39
|
+
static SignInVerified({ createdBy, token }) {
|
|
40
|
+
return ({
|
|
41
|
+
type: 'SignInVerified',
|
|
42
|
+
createdBy,
|
|
43
|
+
payload: { token }
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// static SignedOff({ token, createdBy }) {
|
|
48
|
+
// return ({
|
|
49
|
+
// type: 'SignedOff',
|
|
50
|
+
// createdBy: createdBy,
|
|
51
|
+
// payload: { token }
|
|
52
|
+
// })
|
|
53
|
+
// }
|
|
54
|
+
|
|
55
|
+
// static ApiTokenCreated({ name, createdBy, description, token, expiresAt }) {
|
|
56
|
+
// return ({
|
|
57
|
+
// type: 'ApiTokenCreated',
|
|
58
|
+
// createdBy: createdBy,
|
|
59
|
+
// payload: {
|
|
60
|
+
// name,
|
|
61
|
+
// expiresAt: expiresAt,
|
|
62
|
+
// description: description,
|
|
63
|
+
// token: token
|
|
64
|
+
// }
|
|
65
|
+
// })
|
|
66
|
+
// }
|
|
67
|
+
|
|
68
|
+
// static ApiTokenInvalidated({ createdBy, tokenId }) {
|
|
69
|
+
// return ({
|
|
70
|
+
// type: 'ApiTokenInvalidated',
|
|
71
|
+
// createdBy: createdBy,
|
|
72
|
+
// payload: { tokenId }
|
|
73
|
+
// })
|
|
74
|
+
// }
|
|
75
|
+
|
|
76
|
+
static NameUpdated({ lastName, firstName, createdBy }) {
|
|
77
|
+
return ({
|
|
78
|
+
type: 'NameUpdated',
|
|
79
|
+
createdBy: createdBy,
|
|
80
|
+
payload: {
|
|
81
|
+
lastName,
|
|
82
|
+
firstName
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// TODO: #415
|
|
88
|
+
// static EmailChangeRequested({ email, createdBy }) {
|
|
89
|
+
// return ({
|
|
90
|
+
// type: 'EmailUpdated',
|
|
91
|
+
// createdBy: createdBy,
|
|
92
|
+
// payload: { email }
|
|
93
|
+
// })
|
|
94
|
+
// }
|
|
95
|
+
|
|
96
|
+
// TODO: #415
|
|
97
|
+
// static EmailUpdated({ email, createdBy }) {
|
|
98
|
+
// return ({
|
|
99
|
+
// type: 'EmailUpdated',
|
|
100
|
+
// createdBy: createdBy,
|
|
101
|
+
// payload: { email }
|
|
102
|
+
// })
|
|
103
|
+
// }
|
|
104
|
+
|
|
105
|
+
static WorkspaceJoined({ workspaceId, createdBy }) {
|
|
106
|
+
return ({
|
|
107
|
+
type: 'WorkspaceJoined',
|
|
108
|
+
createdBy,
|
|
109
|
+
payload: { workspaceId }
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static WorkspaceLeft({ workspaceId, createdBy }) {
|
|
114
|
+
return ({
|
|
115
|
+
type: 'WorkspaceLeft',
|
|
116
|
+
createdBy,
|
|
117
|
+
payload: { workspaceId }
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
}
|