@social-mail/social-mail-web-server 1.7.60 → 1.7.63
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/content/json/bad-names.json +591 -0
- package/dist/common/globalEnv.d.ts +1 -0
- package/dist/common/globalEnv.d.ts.map +1 -1
- package/dist/common/globalEnv.js +1 -0
- package/dist/common/globalEnv.js.map +1 -1
- package/dist/server/model/entities/User.d.ts +2 -0
- package/dist/server/model/entities/User.d.ts.map +1 -1
- package/dist/server/model/entities/User.js +13 -0
- package/dist/server/model/entities/User.js.map +1 -1
- package/dist/server/model/events/DomainEvents.d.ts +1 -0
- package/dist/server/model/events/DomainEvents.d.ts.map +1 -1
- package/dist/server/model/events/DomainEvents.js +22 -0
- package/dist/server/model/events/DomainEvents.js.map +1 -1
- package/dist/server/model/events/HostedDomainEvents.d.ts.map +1 -1
- package/dist/server/model/events/HostedDomainEvents.js.map +1 -1
- package/dist/server/model/events/UserEvents.d.ts.map +1 -1
- package/dist/server/model/events/UserEvents.js +5 -0
- package/dist/server/model/events/UserEvents.js.map +1 -1
- package/dist/server/seed/ui/seed-ui.js +1 -1
- package/dist/server/services/EmailAddressService.d.ts +1 -0
- package/dist/server/services/EmailAddressService.d.ts.map +1 -1
- package/dist/server/services/EmailAddressService.js +81 -58
- package/dist/server/services/EmailAddressService.js.map +1 -1
- package/dist/server/services/ui/renderUIClient.d.ts.map +1 -1
- package/dist/server/services/ui/renderUIClient.js +1 -0
- package/dist/server/services/ui/renderUIClient.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/wwwroot/routes/social-mail/user/password/reset/post.d.ts +24 -0
- package/dist/wwwroot/routes/social-mail/user/password/reset/post.d.ts.map +1 -0
- package/dist/wwwroot/routes/social-mail/user/password/reset/post.js +109 -0
- package/dist/wwwroot/routes/social-mail/user/password/reset/post.js.map +1 -0
- package/dist/wwwroot/routes/social-mail/user/signup/get.d.ts +5 -0
- package/dist/wwwroot/routes/social-mail/user/signup/get.d.ts.map +1 -0
- package/dist/wwwroot/routes/social-mail/user/signup/get.js +8 -0
- package/dist/wwwroot/routes/social-mail/user/signup/get.js.map +1 -0
- package/dist/wwwroot/routes/social-mail/user/signup/post.d.ts +4 -12
- package/dist/wwwroot/routes/social-mail/user/signup/post.d.ts.map +1 -1
- package/dist/wwwroot/routes/social-mail/user/signup/post.js +86 -97
- package/dist/wwwroot/routes/social-mail/user/signup/post.js.map +1 -1
- package/package.json +2 -2
- package/src/common/globalEnv.ts +1 -0
- package/src/server/model/entities/User.ts +13 -0
- package/src/server/model/events/DomainEvents.ts +10 -1
- package/src/server/model/events/HostedDomainEvents.ts +1 -0
- package/src/server/model/events/UserEvents.ts +5 -0
- package/src/server/seed/ui/seed-ui.ts +1 -1
- package/src/server/services/EmailAddressService.ts +9 -0
- package/src/server/services/ui/renderUIClient.tsx +1 -0
- package/src/wwwroot/routes/social-mail/user/password/reset/post.tsx +128 -0
- package/src/wwwroot/routes/social-mail/user/signup/get.tsx +9 -0
- package/src/wwwroot/routes/social-mail/user/signup/post.tsx +88 -103
|
@@ -15,6 +15,15 @@ export default class EmailAddressService implements ICacheContainer<EmailAddress
|
|
|
15
15
|
|
|
16
16
|
cache: ObjectCache<EmailAddressService>;
|
|
17
17
|
|
|
18
|
+
@cacheFor()
|
|
19
|
+
public async getHostedDomain(name: string) {
|
|
20
|
+
using scope = globalServices.createScope();
|
|
21
|
+
const db = scope.resolve(SocialMailContext);
|
|
22
|
+
return await db.hostedDomains.where({ name }, (p) => (x) => x.domain.name === p.name)
|
|
23
|
+
.include((x) => x.domain)
|
|
24
|
+
.first();
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
@cacheFor()
|
|
19
28
|
public async getOrCreateDomain(name: string) {
|
|
20
29
|
name = name.toLocaleLowerCase().trim();
|
|
@@ -45,6 +45,7 @@ export const renderUIClient = async (page: Page, view?: string, addScript?: stri
|
|
|
45
45
|
path: globalEnv.path,
|
|
46
46
|
name: globalEnv.name,
|
|
47
47
|
cdn: globalEnv.cdn,
|
|
48
|
+
signupEnabled: globalEnv.signupEnabled,
|
|
48
49
|
externalLogin: globalEnv.externalLogin,
|
|
49
50
|
dnsEnabled: globalEnv.dns?.enabled
|
|
50
51
|
})};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
2
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
3
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
4
|
+
import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
5
|
+
import SocialMailContext from "../../../../../../server/model/SocialMailContext.js";
|
|
6
|
+
import CryptoService from "../../../../../../server/services/CryptoService.js";
|
|
7
|
+
import EmailAddressService from "../../../../../../server/services/EmailAddressService.js";
|
|
8
|
+
import CaptchaService from "../../../../../../server/services/captcha/CaptchaService.js";
|
|
9
|
+
import { IVerification } from "../../../../../../server/services/captcha/IVerification.js";
|
|
10
|
+
import ExternalOtpInService from "../../../../../../server/services/external-otp-in/ExternalOtpInService.js";
|
|
11
|
+
|
|
12
|
+
export interface ISignup {
|
|
13
|
+
username: string;
|
|
14
|
+
userID: number;
|
|
15
|
+
phoneNumber: string;
|
|
16
|
+
captcha: IVerification;
|
|
17
|
+
phone: IVerification;
|
|
18
|
+
password: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Prepare.parseJsonBody
|
|
22
|
+
export default class extends Page {
|
|
23
|
+
|
|
24
|
+
@Inject
|
|
25
|
+
captchaService: CaptchaService;
|
|
26
|
+
|
|
27
|
+
@Inject
|
|
28
|
+
cryptoService: CryptoService;
|
|
29
|
+
|
|
30
|
+
@Inject
|
|
31
|
+
emailAddressService: EmailAddressService;
|
|
32
|
+
|
|
33
|
+
@Inject
|
|
34
|
+
ois: ExternalOtpInService;
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@Inject
|
|
38
|
+
db: SocialMailContext;
|
|
39
|
+
|
|
40
|
+
async run() {
|
|
41
|
+
|
|
42
|
+
const { db } = this;
|
|
43
|
+
|
|
44
|
+
db.verifyFilters = false;
|
|
45
|
+
db.raiseEvents = false;
|
|
46
|
+
|
|
47
|
+
const model = this.body as ISignup;
|
|
48
|
+
|
|
49
|
+
model.username = model.username?.trim();
|
|
50
|
+
if (!model.username) {
|
|
51
|
+
throw new EntityAccessError("Username is required");
|
|
52
|
+
}
|
|
53
|
+
const [username, domain] = model.username.split("@");
|
|
54
|
+
|
|
55
|
+
model.username = username?.trim()?.toLocaleLowerCase()?.replace(/[\.\-]/g, "") + "@" + domain;
|
|
56
|
+
|
|
57
|
+
model.phoneNumber = `+${model.phoneNumber.replace(/[^0-9]/g, "")}`;
|
|
58
|
+
|
|
59
|
+
// console.log(model);
|
|
60
|
+
|
|
61
|
+
// verify captcha...
|
|
62
|
+
await this.captchaService.verify(model.captcha as any);
|
|
63
|
+
|
|
64
|
+
const user = await db.users.where(model, (p) => (x) => x.userName === p.username)
|
|
65
|
+
.first();
|
|
66
|
+
|
|
67
|
+
if (!user) {
|
|
68
|
+
throw new EntityAccessError(`Username ${model.username} not found, make sure it is complete email address.`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!model.phone.id) {
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// check if phone exists...
|
|
75
|
+
const phone = await db.userAuthFactors
|
|
76
|
+
.where(model, (p) => (x) =>
|
|
77
|
+
x.user.userName === p.username
|
|
78
|
+
&& x.phoneNumber === p.phoneNumber
|
|
79
|
+
)
|
|
80
|
+
.first();
|
|
81
|
+
|
|
82
|
+
if (!phone) {
|
|
83
|
+
throw new EntityAccessError(`No phone number is associated with this user, please contact us at support@neurospeech.com .`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!model.phone.id) {
|
|
87
|
+
const v = await this.ois.create([model.phoneNumber]);
|
|
88
|
+
model.phone.id = v.verificationID as any;
|
|
89
|
+
model.phone.code = v.accessCode;
|
|
90
|
+
model.phone.smsConfig = v.externalConfig;
|
|
91
|
+
return this.json(model);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if(model.phone.id) {
|
|
97
|
+
// verify...
|
|
98
|
+
const v = await db.verificationTokens.statements.select({} , { verificationID: model.phone.id as any });
|
|
99
|
+
if (!v.verified) {
|
|
100
|
+
return this.json(model);
|
|
101
|
+
}
|
|
102
|
+
model.phone.verified = "true";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!model.password) {
|
|
106
|
+
return this.json(model);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (model.password.length < 7) {
|
|
110
|
+
throw new EntityAccessError("Password is cannot be less than 7 characters");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (/\s/i.test(model.password)) {
|
|
114
|
+
throw new EntityAccessError("Password must not any whitespace characters");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const passwordSalt = this.cryptoService.generateSalt();
|
|
118
|
+
const passwordHash = this.cryptoService.hash(passwordSalt, model.password);
|
|
119
|
+
model.userID = user.userID;
|
|
120
|
+
await db.users.where(user, (p) => (x) => x.userID === p.userID)
|
|
121
|
+
.update({ passwordSalt, passwordHash}, (p) => (x) => ({
|
|
122
|
+
passwordHash: p.passwordHash,
|
|
123
|
+
passwordSalt: p.passwordSalt
|
|
124
|
+
}));
|
|
125
|
+
return this.json(model);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import { renderUIClient } from "../../../../../server/services/ui/renderUIClient.js";
|
|
3
|
+
|
|
4
|
+
export default class extends Page {
|
|
5
|
+
|
|
6
|
+
async run() {
|
|
7
|
+
return renderUIClient(this, "dist/public/users/signup/SignupPage");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -1,42 +1,45 @@
|
|
|
1
|
-
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
2
1
|
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
3
|
-
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
4
2
|
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
5
3
|
import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
4
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
5
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
6
|
+
import { readFileSync } from "fs";
|
|
6
7
|
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
8
|
+
import VerificationToken from "../../../../../server/model/entities/VerificationToken.js";
|
|
7
9
|
import CryptoService from "../../../../../server/services/CryptoService.js";
|
|
8
10
|
import EmailAddressService from "../../../../../server/services/EmailAddressService.js";
|
|
9
11
|
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
10
|
-
import { IVerification } from "../../../../../server/services/captcha/IVerification.js";
|
|
11
12
|
import ExternalOtpInService from "../../../../../server/services/external-otp-in/ExternalOtpInService.js";
|
|
12
|
-
import { randomUUID } from "crypto";
|
|
13
|
-
import { ContactAddress } from "../../../../../server/model/entities/Contact.js";
|
|
14
|
-
import WebSiteService from "../../../../../server/services/files/WebSiteService.js";
|
|
15
|
-
import { StoreAccountAddress } from "../../../../../server/model/entities/StoreAddress.js";
|
|
16
|
-
import VerificationToken from "../../../../../server/model/entities/VerificationToken.js";
|
|
17
13
|
|
|
18
14
|
export interface ISignup {
|
|
19
15
|
userID: number;
|
|
16
|
+
username: string;
|
|
17
|
+
emailAddress: string;
|
|
20
18
|
password: string;
|
|
21
19
|
name: string;
|
|
22
20
|
phoneNumber: string;
|
|
23
|
-
emailAddress: string;
|
|
24
21
|
isdCode?: string;
|
|
25
22
|
country: string;
|
|
26
23
|
captcha: Partial<VerificationToken>;
|
|
27
24
|
phone: Partial<VerificationToken>;
|
|
28
|
-
email: Partial<VerificationToken>;
|
|
29
|
-
billing?: Partial<StoreAccountAddress>;
|
|
30
|
-
shipping?: Partial<StoreAccountAddress>;
|
|
31
25
|
}
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
const ensureUsername = (name: string) => {
|
|
28
|
+
|
|
29
|
+
const json = JSON.parse(readFileSync("./content/json/bad-names.json","utf8")) as { reserved: string[], partial: string[] };
|
|
30
|
+
|
|
31
|
+
if(json.reserved.includes(name)) {
|
|
32
|
+
throw new EntityAccessError("Username is reserved.");
|
|
33
|
+
}
|
|
34
|
+
for (const iterator of json.partial) {
|
|
35
|
+
if (name.includes(iterator)) {
|
|
36
|
+
throw new EntityAccessError("Username is not acceptable.");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
36
40
|
|
|
37
41
|
@Prepare.parseJsonBody
|
|
38
|
-
|
|
39
|
-
export default class ExternalSignup extends Page {
|
|
42
|
+
export default class extends Page {
|
|
40
43
|
|
|
41
44
|
@Inject
|
|
42
45
|
captchaService: CaptchaService;
|
|
@@ -53,9 +56,6 @@ export default class ExternalSignup extends Page {
|
|
|
53
56
|
@Inject
|
|
54
57
|
db: SocialMailContext;
|
|
55
58
|
|
|
56
|
-
@Inject
|
|
57
|
-
websiteService: WebSiteService;
|
|
58
|
-
|
|
59
59
|
async run() {
|
|
60
60
|
|
|
61
61
|
const { db } = this;
|
|
@@ -65,24 +65,40 @@ export default class ExternalSignup extends Page {
|
|
|
65
65
|
|
|
66
66
|
const model = this.body as ISignup;
|
|
67
67
|
|
|
68
|
-
model.emailAddress = model.
|
|
69
|
-
|
|
68
|
+
model.emailAddress = model.emailAddress.trim().toLowerCase();
|
|
69
|
+
|
|
70
|
+
const [username, domain] = model.emailAddress.split("@", 2);
|
|
71
|
+
model.username = username;
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!storeID) {
|
|
74
|
-
throw new EntityAccessError(`Signup not allowed`);
|
|
73
|
+
if (!/\p{Letter}[\p{Letter}\.\-0-9]{0,50}/iu.test(username)) {
|
|
74
|
+
throw new EntityAccessError(`Invalid email address`);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
model.password = model.password?.trim();
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
model.username = model.username?.trim()?.toLowerCase();
|
|
79
|
+
if (!model.username) {
|
|
80
|
+
throw new EntityAccessError("Username is required");
|
|
81
|
+
}
|
|
82
|
+
ensureUsername(model.username);
|
|
83
|
+
if (!model.password) {
|
|
84
|
+
throw new EntityAccessError("Password is required");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (model.password.length < 7) {
|
|
88
|
+
throw new EntityAccessError("Password is cannot be less than 7 characters");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (/\s/i.test(model.password)) {
|
|
92
|
+
throw new EntityAccessError("Password must not any whitespace characters");
|
|
80
93
|
}
|
|
81
94
|
|
|
82
95
|
model.phoneNumber = `+${model.phoneNumber.replace(/[^0-9]/g, "")}`;
|
|
83
96
|
|
|
97
|
+
// console.log(model);
|
|
98
|
+
|
|
84
99
|
// check if phone number already exists...
|
|
85
|
-
|
|
100
|
+
|
|
101
|
+
for(const v1 of [model.captcha, model.phone]) {
|
|
86
102
|
const { verificationID , accessCode } = v1;
|
|
87
103
|
const vr = await db.verificationTokens.statements.select({}, { verificationID, accessCode });
|
|
88
104
|
if (!vr.verified) {
|
|
@@ -90,27 +106,26 @@ export default class ExternalSignup extends Page {
|
|
|
90
106
|
}
|
|
91
107
|
}
|
|
92
108
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
const hostedDomain = await this.emailAddressService.getHostedDomain(domain);
|
|
110
|
+
if(!hostedDomain || !hostedDomain.allowSignup) {
|
|
111
|
+
throw new EntityAccessError(`Signup for email address ${model.emailAddress} not allowed for domain ${domain}`);
|
|
112
|
+
}
|
|
113
|
+
const emailAddress = model.emailAddress;
|
|
114
|
+
const user = await db.mailboxes.where({ emailAddress}, (p) => (x) => x.emailAddress.emailAddress === p.emailAddress)
|
|
98
115
|
.some();
|
|
99
|
-
if (
|
|
116
|
+
if (user) {
|
|
100
117
|
throw new EntityAccessError(`Email address already exists.`);
|
|
101
118
|
}
|
|
102
119
|
|
|
103
|
-
// check if phone exists...
|
|
104
|
-
const exists = await db.storeAccountPhones
|
|
105
|
-
.where({ phoneNumber, storeID }, (p) => (x) => x.phoneNumberE64 === p.phoneNumber
|
|
106
|
-
&& x.storeAccount.storeID === p.storeID
|
|
107
|
-
).some();
|
|
108
120
|
|
|
121
|
+
// check if phone exists...
|
|
122
|
+
const exists = await db.users
|
|
123
|
+
.where(model, (p) => (x) => x.uniquePhoneNumber === p.phoneNumber)
|
|
124
|
+
.some();
|
|
109
125
|
if (exists) {
|
|
110
126
|
throw new EntityAccessError(`Phone number is already registered.`);
|
|
111
127
|
}
|
|
112
128
|
|
|
113
|
-
model.password = randomUUID();
|
|
114
129
|
const passwordSalt = this.cryptoService.generateSalt();
|
|
115
130
|
const passwordHash = this.cryptoService.hash(passwordSalt, model.password);
|
|
116
131
|
|
|
@@ -118,30 +133,23 @@ export default class ExternalSignup extends Page {
|
|
|
118
133
|
const phoneNumberE64 = model.phoneNumber;
|
|
119
134
|
const name = model.name;
|
|
120
135
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const addresses = [];
|
|
124
|
-
if (model.billing?.title) {
|
|
125
|
-
billingAddress = db.storeAccountAddresses.add(model.billing);
|
|
126
|
-
addresses.push(billingAddress);
|
|
127
|
-
}
|
|
128
|
-
if (model.shipping?.title) {
|
|
129
|
-
shippingAddress = db.storeAccountAddresses.add(model.shipping);
|
|
130
|
-
addresses.push(shippingAddress);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const emailAddressID = await this.emailAddressService.getId(model.emailAddress, model.name);
|
|
136
|
+
const mailboxID = await this.emailAddressService.getId(emailAddress, name);
|
|
137
|
+
const { domainID } = hostedDomain;
|
|
134
138
|
|
|
135
139
|
// create user...
|
|
136
140
|
const account = db.users.add({
|
|
137
|
-
|
|
138
|
-
userName: storeID + ":" + model.emailAddress ,
|
|
141
|
+
userName: model.emailAddress ,
|
|
139
142
|
displayName: name,
|
|
140
143
|
passwordSalt,
|
|
141
144
|
passwordHash,
|
|
142
145
|
multiFactor: false,
|
|
143
146
|
dateUpdated: dateCreated,
|
|
144
|
-
|
|
147
|
+
uniquePhoneNumber: phoneNumberE64,
|
|
148
|
+
roles: [
|
|
149
|
+
db.userRoles.add({
|
|
150
|
+
roleName: "User"
|
|
151
|
+
})
|
|
152
|
+
],
|
|
145
153
|
authFactors: [
|
|
146
154
|
db.userAuthFactors.add({
|
|
147
155
|
phoneNumber: phoneNumberE64,
|
|
@@ -149,66 +157,43 @@ export default class ExternalSignup extends Page {
|
|
|
149
157
|
method: "otp-in",
|
|
150
158
|
dateUpdated: dateCreated
|
|
151
159
|
})
|
|
152
|
-
]
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const contact = db.storeAccounts.add({
|
|
156
|
-
dateCreated,
|
|
157
|
-
user: account,
|
|
158
|
-
storeID,
|
|
159
|
-
/** This is important as name must be unique in the ledger */
|
|
160
|
-
name: `${model.name}(${emailAddressID})`,
|
|
161
|
-
head: "Customer",
|
|
162
|
-
emails: [
|
|
163
|
-
db.storeAccountEmails.add({
|
|
164
|
-
emailAddressID
|
|
165
|
-
})
|
|
166
160
|
],
|
|
167
|
-
|
|
168
|
-
db.
|
|
169
|
-
|
|
161
|
+
userMailboxes:[
|
|
162
|
+
db.userMailboxes.add({
|
|
163
|
+
mailbox: db.mailboxes.add({
|
|
164
|
+
mailboxID,
|
|
165
|
+
domainID,
|
|
166
|
+
uniqueAddress: model.username.replace(/[\-\.]/g, "") + "@" + hostedDomain.domain.name,
|
|
167
|
+
maxStorage: 1024*1024*1024
|
|
168
|
+
})
|
|
170
169
|
})
|
|
171
|
-
]
|
|
172
|
-
addresses
|
|
170
|
+
]
|
|
173
171
|
});
|
|
174
172
|
|
|
175
173
|
await db.saveChanges();
|
|
176
174
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
if (shippingAddress) {
|
|
181
|
-
contact.shippingAddressID = shippingAddress.addressID;
|
|
182
|
-
}
|
|
183
|
-
if (addresses.length) {
|
|
184
|
-
await db.saveChanges();
|
|
185
|
-
}
|
|
175
|
+
// todo pending delete
|
|
176
|
+
// await this.captchaService.delete(model.captcha as any);
|
|
186
177
|
|
|
187
|
-
|
|
178
|
+
model.userID = account.userID;
|
|
188
179
|
|
|
189
|
-
const
|
|
180
|
+
const start = DateTime.now;
|
|
190
181
|
|
|
191
|
-
//
|
|
182
|
+
// add login cookie..
|
|
183
|
+
const expiry = start.addDays(30);
|
|
192
184
|
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// create login session...
|
|
198
|
-
const loginSession = await db.loginSessions.statements.insert({
|
|
199
|
-
userID,
|
|
200
|
-
dateUpdated,
|
|
185
|
+
model.userID = account.userID;
|
|
186
|
+
const session = await db.loginSessions.statements.insert({
|
|
187
|
+
userID: account.userID,
|
|
201
188
|
start,
|
|
202
189
|
expiry,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
status: "created"
|
|
190
|
+
status: "created",
|
|
191
|
+
invalid: false
|
|
206
192
|
});
|
|
207
|
-
|
|
208
193
|
await this.sessionUser.setAuthCookie({
|
|
209
|
-
userID:
|
|
210
|
-
id:
|
|
211
|
-
expiry: expiry.asJSDate,
|
|
194
|
+
userID: session.userID,
|
|
195
|
+
id: session.sessionID,
|
|
196
|
+
expiry: session.expiry.asJSDate,
|
|
212
197
|
version: "1.1",
|
|
213
198
|
active: true
|
|
214
199
|
});
|