Skip to content

Commit 20dce0a

Browse files
committed
fix #7781 -- ensure all newly created accounts have at least one project
- did this by some refactoring to make sure that account creation via SSO also calls the "new" (3 years old?) account creation actions implementation instead of the ancient one.
1 parent 35cf42e commit 20dce0a

File tree

6 files changed

+44
-35
lines changed

6 files changed

+44
-35
lines changed

src/packages/database/postgres-server-queries.coffee

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,14 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
619619
'account_id = $::UUID' : opts.account_id
620620
cb : opts.cb
621621

622+
# DEPRECATED: use import accountCreationActions from "@cocalc/server/accounts/account-creation-actions"; instead!!!!
622623
do_account_creation_actions: (opts) =>
623624
opts = defaults opts,
624625
email_address : required
625626
account_id : required
626627
cb : required
627628
dbg = @_dbg("do_account_creation_actions(email_address='#{opts.email_address}')")
629+
dbg("**DEPRECATED!** This will miss doing important things, e.g., creating initial project.")
628630
@account_creation_actions
629631
email_address : opts.email_address
630632
cb : (err, actions) =>

src/packages/next/components/auth/sign-up.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
GoogleReCaptchaProvider,
1010
useGoogleReCaptcha,
1111
} from "react-google-recaptcha-v3";
12-
1312
import Markdown from "@cocalc/frontend/editors/slate/static-markdown";
1413
import {
1514
CONTACT_TAG,

src/packages/server/accounts/account-creation-actions.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,32 @@ import { getProject } from "@cocalc/server/projects/control";
1010

1111
const log = getLogger("server:accounts:creation-actions");
1212

13-
export default async function accountCreationActions(
14-
email_address: string,
15-
account_id: string,
16-
tags?: string[],
17-
): Promise<void> {
13+
export default async function accountCreationActions({
14+
email_address,
15+
account_id,
16+
tags,
17+
}: {
18+
email_address?: string;
19+
account_id: string;
20+
tags?: string[];
21+
}): Promise<void> {
1822
log.debug({ account_id, email_address, tags });
19-
const pool = getPool();
20-
const { rows } = await pool.query(
21-
"SELECT action FROM account_creation_actions WHERE email_address=$1 AND expire > NOW()",
22-
[email_address],
23-
);
23+
2424
let numProjects = 0;
25-
for (const { action } of rows) {
26-
if (action.action == "add_to_project") {
27-
const { project_id, group } = action;
28-
await addUserToProject({ project_id, account_id, group });
29-
numProjects += 1;
30-
} else {
31-
throw Error(`unknown account creation action "${action.action}"`);
25+
if (email_address != null) {
26+
const pool = getPool();
27+
const { rows } = await pool.query(
28+
"SELECT action FROM account_creation_actions WHERE email_address=$1 AND expire > NOW()",
29+
[email_address],
30+
);
31+
for (const { action } of rows) {
32+
if (action.action == "add_to_project") {
33+
const { project_id, group } = action;
34+
await addUserToProject({ project_id, account_id, group });
35+
numProjects += 1;
36+
} else {
37+
throw Error(`unknown account creation action "${action.action}"`);
38+
}
3239
}
3340
}
3441
log.debug("added user to", numProjects, "projects");

src/packages/server/accounts/create-account.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default async function createAccount({
5555
],
5656
);
5757
if (email) {
58-
await accountCreationActions(email, account_id, tags);
58+
await accountCreationActions({ email_address: email, account_id, tags });
5959
}
6060
await creationActionsDone(account_id);
6161
} catch (error) {

src/packages/server/accounts/set-email-address.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import sendEmailVerification from "./send-email-verification";
3636
export default async function setEmailAddress(
3737
account_id: string,
3838
email_address: string,
39-
password: string
39+
password: string,
4040
): Promise<void> {
4141
if (!isValidUUID(account_id)) {
4242
throw Error("account_id is not valid");
@@ -52,7 +52,7 @@ export default async function setEmailAddress(
5252
const pool = getPool();
5353
const { rows } = await pool.query(
5454
"SELECT email_address, password_hash, email_address_verified, stripe_customer_id FROM accounts WHERE account_id=$1",
55-
[account_id]
55+
[account_id],
5656
);
5757
if (rows.length == 0) {
5858
throw Error("no such account");
@@ -73,7 +73,7 @@ export default async function setEmailAddress(
7373
if (!password_hash) {
7474
await pool.query(
7575
"UPDATE accounts SET password_hash=$1, WHERE account_id=$2",
76-
[passwordHash(password), account_id]
76+
[passwordHash(password), account_id],
7777
);
7878
}
7979
throw new Error(`You are not allowed to change your email address`);
@@ -82,15 +82,15 @@ export default async function setEmailAddress(
8282
// you're also not allowed to change your email address to one that's covered by an exclusive strategy
8383
if (checkRequiredSSO({ strategies, email: email_address }) != null) {
8484
throw new Error(
85-
`You are not allowed to change your email address to this one`
85+
`You are not allowed to change your email address to this one`,
8686
);
8787
}
8888

8989
if (!password_hash) {
9090
// setting both the email_address *and* password at once.
9191
await pool.query(
9292
"UPDATE accounts SET password_hash=$1, email_address=$2 WHERE account_id=$3",
93-
[passwordHash(password), email_address, account_id]
93+
[passwordHash(password), email_address, account_id],
9494
);
9595
return;
9696
}
@@ -104,12 +104,12 @@ export default async function setEmailAddress(
104104
(
105105
await pool.query(
106106
"SELECT COUNT(*)::INT FROM accounts WHERE email_address=$1",
107-
[email_address]
107+
[email_address],
108108
)
109109
).rows[0].count > 0
110110
) {
111111
throw Error(
112-
`email address "${email_address}" is already in use by another account`
112+
`email address "${email_address}" is already in use by another account`,
113113
);
114114
}
115115

@@ -120,7 +120,7 @@ export default async function setEmailAddress(
120120
]);
121121

122122
// Do any pending account creation actions for this email.
123-
await accountCreationActions(email_address, account_id);
123+
await accountCreationActions({ email_address, account_id });
124124
await creationActionsDone(account_id);
125125

126126
// sync new email address with stripe
@@ -130,7 +130,7 @@ export default async function setEmailAddress(
130130
await stripe.update_database();
131131
} catch (err) {
132132
console.warn(
133-
`ERROR syncing new email address with stripe: ${err} – ignoring`
133+
`ERROR syncing new email address with stripe: ${err} – ignoring`,
134134
);
135135
}
136136
}

src/packages/server/auth/sso/passport-login.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import Cookies from "cookies";
2222
import * as _ from "lodash";
2323
import { isEmpty } from "lodash";
24-
2524
import base_path from "@cocalc/backend/base-path";
2625
import getLogger from "@cocalc/backend/logger";
2726
import { set_email_address_verified } from "@cocalc/database/postgres/account-queries";
@@ -43,6 +42,7 @@ import getEmailAddress from "../../accounts/get-email-address";
4342
import { emailBelongsToDomain, getEmailDomain } from "./check-required-sso";
4443
import { SSO_API_KEY_COOKIE_NAME } from "./consts";
4544
import isBanned from "@cocalc/server/accounts/is-banned";
45+
import accountCreationActions from "@cocalc/server/accounts/account-creation-actions";
4646

4747
const logger = getLogger("server:auth:sso:passport-login");
4848

@@ -423,17 +423,18 @@ export class PassportLogin {
423423

424424
// if we know the email address provided by the SSO strategy,
425425
// we execute the account creation actions and set the address to be verified
426+
await accountCreationActions({
427+
email_address: locals.email_address,
428+
account_id: locals.account_id,
429+
// TODO: tags should be encoded in URL and passed here, but that's
430+
// not implemented
431+
});
426432
if (locals.email_address != null) {
427-
const actions = cb2(this.database.do_account_creation_actions, {
428-
email_address: locals.email_address,
429-
account_id: locals.account_id,
430-
});
431-
const verify = set_email_address_verified({
433+
await set_email_address_verified({
432434
db: this.database,
433435
account_id: locals.account_id,
434436
email_address: locals.email_address,
435437
});
436-
await Promise.all([actions, verify]);
437438
}
438439

439440
// log the newly created account

0 commit comments

Comments
 (0)