@nymphjs/tilmeld 1.0.0-beta.2 → 1.0.0-beta.21
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/CHANGELOG.md +106 -0
- package/README.md +13 -0
- package/dist/Group.js +49 -23
- package/dist/Group.js.map +1 -1
- package/dist/Tilmeld.d.ts +5 -2
- package/dist/Tilmeld.js +151 -60
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +56 -3
- package/dist/User.js +306 -45
- package/dist/User.js.map +1 -1
- package/dist/conf/d.d.ts +3 -1
- package/dist/conf/defaults.js +15 -4
- package/dist/conf/defaults.js.map +1 -1
- package/dist/enforceTilmeld.d.ts +3 -0
- package/dist/enforceTilmeld.js +22 -0
- package/dist/enforceTilmeld.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +22 -19
- package/src/Group.ts +70 -23
- package/src/Tilmeld.ts +225 -76
- package/src/User.ts +483 -49
- package/src/conf/d.ts +16 -7
- package/src/conf/defaults.ts +17 -4
- package/src/enforceTilmeld.ts +20 -0
- package/src/index.ts +2 -0
package/src/Tilmeld.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { AccessControlError } from './errors';
|
|
|
15
15
|
import Group from './Group';
|
|
16
16
|
import User, { UserData } from './User';
|
|
17
17
|
import { AccessControlData } from './Tilmeld.types';
|
|
18
|
+
import { enforceTilmeld } from './enforceTilmeld';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* A user and group system for Nymph.js.
|
|
@@ -73,6 +74,11 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
73
74
|
*/
|
|
74
75
|
private skipAuthenticate = false;
|
|
75
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Used to avoid infinite loop.
|
|
79
|
+
*/
|
|
80
|
+
private alreadyLoggedOutSwitch = false;
|
|
81
|
+
|
|
76
82
|
/**
|
|
77
83
|
* Create a new instance of Tilmeld.
|
|
78
84
|
*
|
|
@@ -84,6 +90,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
84
90
|
|
|
85
91
|
/**
|
|
86
92
|
* This is used internally by Nymph. Don't call it yourself.
|
|
93
|
+
*
|
|
87
94
|
* @returns A clone of this instance.
|
|
88
95
|
*/
|
|
89
96
|
public clone() {
|
|
@@ -105,6 +112,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
105
112
|
*/
|
|
106
113
|
public init(nymph: Nymph) {
|
|
107
114
|
this.nymph = nymph;
|
|
115
|
+
const tilmeld = this;
|
|
108
116
|
|
|
109
117
|
// Set up access control hooks when Nymph is called.
|
|
110
118
|
if (this.nymph.driver == null) {
|
|
@@ -112,18 +120,18 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
// Configure the classes.
|
|
115
|
-
class NymphUser extends User {
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
class NymphUser extends User {
|
|
124
|
+
static nymph: Nymph = nymph;
|
|
125
|
+
static tilmeld: Tilmeld = tilmeld;
|
|
126
|
+
}
|
|
118
127
|
(NymphUser as any).skipOnClone = true;
|
|
119
|
-
this.User = NymphUser;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
this.User = this.nymph.addEntityClass(NymphUser);
|
|
129
|
+
class NymphGroup extends Group {
|
|
130
|
+
static nymph: Nymph = nymph;
|
|
131
|
+
static tilmeld: Tilmeld = tilmeld;
|
|
132
|
+
}
|
|
124
133
|
(NymphUser as any).skipOnClone = true;
|
|
125
|
-
this.Group = NymphGroup;
|
|
126
|
-
this.nymph.addEntityClass(NymphGroup);
|
|
134
|
+
this.Group = this.nymph.addEntityClass(NymphGroup);
|
|
127
135
|
|
|
128
136
|
this.initAccessControl();
|
|
129
137
|
if (this.request != null && !this.skipAuthenticate) {
|
|
@@ -150,12 +158,12 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
150
158
|
|
|
151
159
|
private initAccessControl() {
|
|
152
160
|
// Check for the skip access control option and add AC selectors.
|
|
153
|
-
const handleQuery =
|
|
161
|
+
const handleQuery = function (
|
|
154
162
|
nymph: Nymph,
|
|
155
163
|
options: Options,
|
|
156
164
|
selectors: FormattedSelector[]
|
|
157
165
|
) {
|
|
158
|
-
const tilmeld = nymph
|
|
166
|
+
const tilmeld = enforceTilmeld(nymph);
|
|
159
167
|
if (
|
|
160
168
|
!options ||
|
|
161
169
|
!('skipAc' in options) ||
|
|
@@ -195,7 +203,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
195
203
|
nymph: Nymph,
|
|
196
204
|
entity: EntityInterface
|
|
197
205
|
) {
|
|
198
|
-
const tilmeld = nymph
|
|
206
|
+
const tilmeld = enforceTilmeld(nymph);
|
|
199
207
|
if (
|
|
200
208
|
typeof entity.$tilmeldDeleteSkipAC === 'function' &&
|
|
201
209
|
entity.$tilmeldDeleteSkipAC()
|
|
@@ -231,7 +239,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
231
239
|
nymph: Nymph,
|
|
232
240
|
entity: EntityInterface & AccessControlData
|
|
233
241
|
) {
|
|
234
|
-
const tilmeld = nymph
|
|
242
|
+
const tilmeld = enforceTilmeld(nymph);
|
|
235
243
|
if (!entity) {
|
|
236
244
|
return;
|
|
237
245
|
}
|
|
@@ -342,11 +350,10 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
342
350
|
}
|
|
343
351
|
|
|
344
352
|
if (
|
|
345
|
-
(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
!tilmeld.gatekeeper('tilmeld/admin')
|
|
353
|
+
(originalAc.user && !originalAc.user.$is(newAc.user)) ||
|
|
354
|
+
(!originalAc.user &&
|
|
355
|
+
newAc.user &&
|
|
356
|
+
!newAc.user.$is(tilmeld.currentUser))
|
|
350
357
|
) {
|
|
351
358
|
throw new AccessControlError(
|
|
352
359
|
'No permission to assign to another user.'
|
|
@@ -359,8 +366,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
359
366
|
!(
|
|
360
367
|
newAc.group.$is(tilmeld.currentUser?.group) ||
|
|
361
368
|
newAc.group.$inArray(tilmeld.currentUser?.groups ?? [])
|
|
362
|
-
)
|
|
363
|
-
!tilmeld.gatekeeper('tilmeld/admin')
|
|
369
|
+
)
|
|
364
370
|
) {
|
|
365
371
|
throw new AccessControlError(
|
|
366
372
|
'No permission to assign to another group.'
|
|
@@ -398,7 +404,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
398
404
|
nymph: Nymph,
|
|
399
405
|
entity: EntityInterface & AccessControlData
|
|
400
406
|
) {
|
|
401
|
-
const tilmeld = nymph
|
|
407
|
+
const tilmeld = enforceTilmeld(nymph);
|
|
402
408
|
const user = tilmeld.currentUser;
|
|
403
409
|
if (
|
|
404
410
|
user != null &&
|
|
@@ -530,14 +536,6 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
530
536
|
) {
|
|
531
537
|
const user = this.currentUser;
|
|
532
538
|
|
|
533
|
-
if (
|
|
534
|
-
user != null &&
|
|
535
|
-
(user.abilities?.indexOf('system/admin') ?? -1) !== -1
|
|
536
|
-
) {
|
|
537
|
-
// The user is a system admin, so they can see everything.
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
539
|
if (options == null) {
|
|
542
540
|
throw new Error('No options in argument.');
|
|
543
541
|
} else if (
|
|
@@ -669,7 +667,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
669
667
|
* - FULL_ACCESS, the user has read, write, and delete access to the entity,
|
|
670
668
|
* as well as being able to manage its access controls and ownership.
|
|
671
669
|
*
|
|
672
|
-
* These properties
|
|
670
|
+
* These properties default to:
|
|
673
671
|
*
|
|
674
672
|
* - acUser = TilmeldAccessLevels.FULL_ACCESS
|
|
675
673
|
* - acGroup = TilmeldAccessLevels.READ_ACCESS
|
|
@@ -684,9 +682,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
684
682
|
* The following conditions will result in different checks, which determine
|
|
685
683
|
* whether the check passes:
|
|
686
684
|
*
|
|
687
|
-
* - The user has the "system/admin" ability. (Always true.)
|
|
688
685
|
* - It is a user or group. (True for READ_ACCESS or Tilmeld admins.)
|
|
689
|
-
* - The entity has no "user" and no "group". (Always true.)
|
|
690
686
|
* - No user is logged in. (Check other AC.)
|
|
691
687
|
* - The entity is the user. (Always true.)
|
|
692
688
|
* - It is the user's primary group. (True for READ_ACCESS.)
|
|
@@ -727,30 +723,22 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
727
723
|
userOrEmpty = user;
|
|
728
724
|
}
|
|
729
725
|
|
|
730
|
-
if (userOrEmpty.$gatekeeper('system/admin')) {
|
|
731
|
-
return true;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
726
|
// Users and groups are always readable. Editable by Tilmeld admins.
|
|
735
727
|
if (
|
|
736
728
|
(entity instanceof User || entity instanceof Group) &&
|
|
737
729
|
(type === TilmeldAccessLevels.READ_ACCESS ||
|
|
738
|
-
userOrEmpty
|
|
730
|
+
userOrEmpty.abilities?.includes('tilmeld/admin') ||
|
|
731
|
+
userOrEmpty.abilities?.includes('system/admin'))
|
|
739
732
|
) {
|
|
740
733
|
return true;
|
|
741
734
|
}
|
|
742
735
|
|
|
743
|
-
// Entities with no owners are always editable.
|
|
744
|
-
if (entity.user == null && entity.group == null) {
|
|
745
|
-
return true;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
736
|
// Load access control, since we need it now...
|
|
749
737
|
const acUser = entity.acUser ?? TilmeldAccessLevels.FULL_ACCESS;
|
|
750
738
|
const acGroup = entity.acGroup ?? TilmeldAccessLevels.READ_ACCESS;
|
|
751
739
|
const acOther = entity.acOther ?? TilmeldAccessLevels.NO_ACCESS;
|
|
752
740
|
|
|
753
|
-
if (userOrNull
|
|
741
|
+
if (userOrNull == null) {
|
|
754
742
|
return acOther >= type;
|
|
755
743
|
}
|
|
756
744
|
|
|
@@ -860,7 +848,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
860
848
|
userOrEmpty = user;
|
|
861
849
|
}
|
|
862
850
|
|
|
863
|
-
if (userOrEmpty
|
|
851
|
+
if (userOrEmpty.abilities?.includes('system/admin')) {
|
|
864
852
|
return true;
|
|
865
853
|
}
|
|
866
854
|
|
|
@@ -948,7 +936,7 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
948
936
|
guid: guid,
|
|
949
937
|
}
|
|
950
938
|
);
|
|
951
|
-
if (!user || !user.guid
|
|
939
|
+
if (!user || !user.guid) {
|
|
952
940
|
return null;
|
|
953
941
|
}
|
|
954
942
|
|
|
@@ -956,7 +944,17 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
956
944
|
}
|
|
957
945
|
|
|
958
946
|
/**
|
|
959
|
-
* Check for
|
|
947
|
+
* Check for TILMELDAUTH and TILMELDSWITCH tokens, and, if set, authenticate
|
|
948
|
+
* from it/them.
|
|
949
|
+
*
|
|
950
|
+
* You can also call this function after setting `response.locals.user` to the
|
|
951
|
+
* user you want to authenticate. You *should* check for `user.enabled` before
|
|
952
|
+
* setting this variable, unless you explicitly want to log in as a disabled
|
|
953
|
+
* user. (The user must be an instance of the User class for this Tilmeld
|
|
954
|
+
* instance.)
|
|
955
|
+
*
|
|
956
|
+
* This function will set `response.locals.user` to the logged in user on
|
|
957
|
+
* successful authentication.
|
|
960
958
|
*
|
|
961
959
|
* @param skipXsrfToken Skip the XSRF token check.
|
|
962
960
|
* @returns True if a user was authenticated, false on any failure.
|
|
@@ -966,30 +964,52 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
966
964
|
return false;
|
|
967
965
|
}
|
|
968
966
|
|
|
967
|
+
if (
|
|
968
|
+
this.response &&
|
|
969
|
+
this.response.locals.user &&
|
|
970
|
+
this.response.locals.user instanceof this.User
|
|
971
|
+
) {
|
|
972
|
+
// The user has already been authenticated through some other means.
|
|
973
|
+
const user = this.response.locals.user;
|
|
974
|
+
this.fillSession(user);
|
|
975
|
+
return true;
|
|
976
|
+
}
|
|
977
|
+
|
|
969
978
|
const cookies = this.request.cookies ?? {};
|
|
970
979
|
|
|
971
980
|
// If a client does't support cookies, they can use the X-TILMELDAUTH header
|
|
972
981
|
// to provide the auth token.
|
|
973
982
|
let fromAuthHeader = false;
|
|
974
983
|
let authToken: string;
|
|
984
|
+
let switchToken: string | null;
|
|
975
985
|
if (this.request.header('x-tilmeldauth') != null) {
|
|
976
986
|
fromAuthHeader = true;
|
|
977
987
|
authToken = this.request.header('x-tilmeldauth') as string;
|
|
988
|
+
switchToken =
|
|
989
|
+
(this.request.header('x-tilmeldswitch') as string) ||
|
|
990
|
+
'TILMELDSWITCH' in cookies
|
|
991
|
+
? cookies.TILMELDSWITCH
|
|
992
|
+
: null;
|
|
978
993
|
} else if ('TILMELDAUTH' in cookies) {
|
|
979
994
|
fromAuthHeader = false;
|
|
980
995
|
authToken = cookies.TILMELDAUTH;
|
|
996
|
+
switchToken = 'TILMELDSWITCH' in cookies ? cookies.TILMELDSWITCH : null;
|
|
981
997
|
} else {
|
|
982
998
|
return false;
|
|
983
999
|
}
|
|
984
1000
|
|
|
985
|
-
let
|
|
1001
|
+
let authExtract: { guid: string; issued: Date; expire: Date } | null;
|
|
1002
|
+
let switchExtract: { guid: string; expire: Date } | null;
|
|
986
1003
|
if (
|
|
987
1004
|
skipXsrfToken ||
|
|
988
1005
|
this.request.originalUrl.startsWith(this.config.setupPath)
|
|
989
1006
|
) {
|
|
990
1007
|
// The request is for the setup app, or we were told to skip the XSRF
|
|
991
1008
|
// check, so don't check for the XSRF token.
|
|
992
|
-
|
|
1009
|
+
authExtract = this.config.jwtExtract(this.config, authToken);
|
|
1010
|
+
switchExtract = switchToken
|
|
1011
|
+
? this.config.jwtExtract(this.config, switchToken)
|
|
1012
|
+
: null;
|
|
993
1013
|
} else {
|
|
994
1014
|
// The request is for something else, so check for a valid XSRF token,
|
|
995
1015
|
// unless the auth token is provided by a header (instead of a cookie).
|
|
@@ -998,28 +1018,62 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
998
1018
|
return false;
|
|
999
1019
|
}
|
|
1000
1020
|
|
|
1001
|
-
|
|
1021
|
+
authExtract = this.config.jwtExtract(this.config, authToken, xsrfToken);
|
|
1022
|
+
switchExtract = switchToken
|
|
1023
|
+
? this.config.jwtExtract(this.config, switchToken)
|
|
1024
|
+
: null;
|
|
1002
1025
|
}
|
|
1003
1026
|
|
|
1004
|
-
if (
|
|
1027
|
+
if (authExtract == null) {
|
|
1005
1028
|
this.logout();
|
|
1006
1029
|
return false;
|
|
1007
1030
|
}
|
|
1008
|
-
const { guid, expire } =
|
|
1031
|
+
const { guid, issued, expire } = authExtract;
|
|
1032
|
+
const { guid: switchGuid, expire: switchExpire } = switchExtract || {
|
|
1033
|
+
guid: null,
|
|
1034
|
+
expire: null,
|
|
1035
|
+
};
|
|
1009
1036
|
|
|
1010
1037
|
const user = this.User.factorySync(guid);
|
|
1011
|
-
if (
|
|
1038
|
+
if (
|
|
1039
|
+
user.guid == null ||
|
|
1040
|
+
!user.enabled ||
|
|
1041
|
+
expire.getTime() <= Date.now() ||
|
|
1042
|
+
issued.getTime() > Date.now() ||
|
|
1043
|
+
(user.revokeTokenDate != null && issued.getTime() <= user.revokeTokenDate)
|
|
1044
|
+
) {
|
|
1012
1045
|
this.logout();
|
|
1013
1046
|
return false;
|
|
1014
1047
|
}
|
|
1015
1048
|
|
|
1016
|
-
if (
|
|
1049
|
+
if (switchGuid && switchExpire && switchExpire.getTime() > Date.now()) {
|
|
1050
|
+
// Load the switch user.
|
|
1051
|
+
const switchUser = this.User.factorySync(switchGuid);
|
|
1052
|
+
if (switchUser.guid == null) {
|
|
1053
|
+
this.logoutSwitch();
|
|
1054
|
+
} else {
|
|
1055
|
+
this.fillSession(switchUser);
|
|
1056
|
+
|
|
1057
|
+
if (this.response) {
|
|
1058
|
+
this.response.locals.user = switchUser;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
return true;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if (expire.getTime() < Date.now() + this.config.jwtRenew * 1000) {
|
|
1017
1066
|
// If the user is less than renew time from needing a new token, give them
|
|
1018
1067
|
// a new one.
|
|
1019
1068
|
this.login(user, fromAuthHeader);
|
|
1020
1069
|
} else {
|
|
1021
1070
|
this.fillSession(user);
|
|
1022
1071
|
}
|
|
1072
|
+
|
|
1073
|
+
if (this.response) {
|
|
1074
|
+
this.response.locals.user = user;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1023
1077
|
return true;
|
|
1024
1078
|
}
|
|
1025
1079
|
|
|
@@ -1027,26 +1081,86 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
1027
1081
|
* Logs the given user into the system.
|
|
1028
1082
|
*
|
|
1029
1083
|
* @param user The user.
|
|
1030
|
-
* @param sendAuthHeader
|
|
1084
|
+
* @param sendAuthHeader Send the auth token as a custom header.
|
|
1085
|
+
* @param sendCookie Send the auth token as a cookie.
|
|
1031
1086
|
* @returns True on success, false on failure.
|
|
1032
1087
|
*/
|
|
1033
|
-
public login(
|
|
1088
|
+
public login(
|
|
1089
|
+
user: User & UserData,
|
|
1090
|
+
sendAuthHeader: boolean,
|
|
1091
|
+
sendCookie = true
|
|
1092
|
+
) {
|
|
1034
1093
|
if (user.guid != null && user.enabled) {
|
|
1035
|
-
if (this.response
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1094
|
+
if (this.response) {
|
|
1095
|
+
if (!this.response.headersSent) {
|
|
1096
|
+
const token = this.config.jwtBuilder(this.config, user);
|
|
1097
|
+
|
|
1098
|
+
if (sendCookie) {
|
|
1099
|
+
const appUrl = new URL(this.config.appUrl);
|
|
1100
|
+
this.response.cookie('TILMELDAUTH', token, {
|
|
1101
|
+
domain: this.config.cookieDomain,
|
|
1102
|
+
path: this.config.cookiePath,
|
|
1103
|
+
maxAge: this.config.jwtExpire * 1000,
|
|
1104
|
+
secure: appUrl.protocol === 'https',
|
|
1105
|
+
httpOnly: false, // Allow JS access (for CSRF protection).
|
|
1106
|
+
sameSite: appUrl.protocol === 'https' ? 'lax' : 'strict',
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
if (sendAuthHeader) {
|
|
1111
|
+
this.response.set('X-TILMELDAUTH', token);
|
|
1112
|
+
}
|
|
1048
1113
|
}
|
|
1114
|
+
|
|
1115
|
+
this.response.locals.user = user;
|
|
1049
1116
|
}
|
|
1117
|
+
|
|
1118
|
+
this.fillSession(user);
|
|
1119
|
+
return true;
|
|
1120
|
+
}
|
|
1121
|
+
return false;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* Adds a switch auth token for the given user.
|
|
1126
|
+
*
|
|
1127
|
+
* This effectively logs the current user in to the system as the given user.
|
|
1128
|
+
*
|
|
1129
|
+
* @param user The user.
|
|
1130
|
+
* @param sendAuthHeader Send the auth token as a custom header.
|
|
1131
|
+
* @param sendCookie Send the auth token as a cookie.
|
|
1132
|
+
* @returns True on success, false on failure.
|
|
1133
|
+
*/
|
|
1134
|
+
public loginSwitch(
|
|
1135
|
+
user: User & UserData,
|
|
1136
|
+
sendAuthHeader: boolean,
|
|
1137
|
+
sendCookie = true
|
|
1138
|
+
) {
|
|
1139
|
+
if (user.guid != null) {
|
|
1140
|
+
if (this.response) {
|
|
1141
|
+
if (!this.response.headersSent) {
|
|
1142
|
+
const token = this.config.jwtBuilder(this.config, user, true);
|
|
1143
|
+
|
|
1144
|
+
if (sendCookie) {
|
|
1145
|
+
const appUrl = new URL(this.config.appUrl);
|
|
1146
|
+
this.response.cookie('TILMELDSWITCH', token, {
|
|
1147
|
+
domain: this.config.cookieDomain,
|
|
1148
|
+
path: this.config.cookiePath,
|
|
1149
|
+
maxAge: this.config.jwtSwitchExpire * 1000,
|
|
1150
|
+
secure: appUrl.protocol === 'https',
|
|
1151
|
+
httpOnly: false, // Allow JS access (for PubSub auth token).
|
|
1152
|
+
sameSite: appUrl.protocol === 'https' ? 'lax' : 'strict',
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if (sendAuthHeader) {
|
|
1157
|
+
this.response.set('X-TILMELDSWITCH', token);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
this.response.locals.user = user;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1050
1164
|
this.fillSession(user);
|
|
1051
1165
|
return true;
|
|
1052
1166
|
}
|
|
@@ -1055,15 +1169,50 @@ export default class Tilmeld implements TilmeldInterface {
|
|
|
1055
1169
|
|
|
1056
1170
|
/**
|
|
1057
1171
|
* Logs the current user out of the system.
|
|
1172
|
+
*
|
|
1173
|
+
* @param clearCookie Clear the auth cookie. (Also send a header.)
|
|
1058
1174
|
*/
|
|
1059
|
-
public logout() {
|
|
1175
|
+
public logout(clearCookie = true) {
|
|
1176
|
+
if (this.request && !this.alreadyLoggedOutSwitch) {
|
|
1177
|
+
const cookies = this.request.cookies ?? {};
|
|
1178
|
+
|
|
1179
|
+
if ('TILMELDSWITCH' in cookies) {
|
|
1180
|
+
this.alreadyLoggedOutSwitch = true;
|
|
1181
|
+
return this.logoutSwitch(clearCookie);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1060
1185
|
this.clearSession();
|
|
1061
|
-
if (this.response
|
|
1062
|
-
this.response.
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1186
|
+
if (this.response) {
|
|
1187
|
+
if (clearCookie && !this.response.headersSent) {
|
|
1188
|
+
this.response.clearCookie('TILMELDAUTH', {
|
|
1189
|
+
domain: this.config.cookieDomain,
|
|
1190
|
+
path: this.config.cookiePath,
|
|
1191
|
+
});
|
|
1192
|
+
this.response.set('X-TILMELDAUTH', '');
|
|
1193
|
+
}
|
|
1194
|
+
this.response.locals.user = null;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Clears the switch user out of the system.
|
|
1200
|
+
*
|
|
1201
|
+
* @param clearCookie Clear the auth cookie. (Also send a header.)
|
|
1202
|
+
*/
|
|
1203
|
+
public logoutSwitch(clearCookie = true) {
|
|
1204
|
+
this.clearSession();
|
|
1205
|
+
if (this.response) {
|
|
1206
|
+
if (clearCookie && !this.response.headersSent) {
|
|
1207
|
+
this.response.clearCookie('TILMELDSWITCH', {
|
|
1208
|
+
domain: this.config.cookieDomain,
|
|
1209
|
+
path: this.config.cookiePath,
|
|
1210
|
+
});
|
|
1211
|
+
this.response.set('X-TILMELDSWITCH', '');
|
|
1212
|
+
}
|
|
1213
|
+
this.response.locals.user = null;
|
|
1214
|
+
|
|
1215
|
+
this.authenticate();
|
|
1067
1216
|
}
|
|
1068
1217
|
}
|
|
1069
1218
|
|