Skip to content

Commit 41fcc19

Browse files
committed
feat: update
1 parent b654c9c commit 41fcc19

File tree

11 files changed

+652
-60
lines changed

11 files changed

+652
-60
lines changed

dev-commands/dev/default.nix

+17-7
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ config.mkScripts {
9494
databaseAnonymousPassword="${(import "${pkgs.rootProjectDir}/config/ignored/passwords.nix").DATABASE_ANONYMOUS_PASSWORD}" \
9595
oauthGithubClientSecret="${(import "${pkgs.rootProjectDir}/config/ignored/github-oauth.nix").CLIENT_SECRET}" \
9696
spago --config spago-api-server.dhall run --main ApiServer.Main --node-args '\
97-
--export-gql-schema-path "${pkgs.rootProjectDir}/schemas/schema.graphql" \
98-
--export-json-schema-path "${pkgs.rootProjectDir}/schemas/schema.json" \
97+
--exportGqlSchemaPath "${pkgs.rootProjectDir}/schemas/schema.graphql" \
98+
--exportJsonSchemaPath "${pkgs.rootProjectDir}/schemas/schema.json" \
9999
--port 3000 \
100-
--client-port 3001 \
100+
--clientPort 3001 \
101101
--hostname localhost \
102102
--rootUrl "http://localhost:3000" \
103-
--database-name "${(import "${pkgs.rootProjectDir}/config/public/database.nix").DATABASE_NAME}" \
104-
--database-hostname "$POSTGRES_HOST" \
105-
--database-port "$POSTGRES_PORT" \
106-
--oauth-github-client-id "${(import "${pkgs.rootProjectDir}/config/ignored/github-oauth.nix").CLIENT_ID}" \
103+
--databaseName "${(import "${pkgs.rootProjectDir}/config/public/database.nix").DATABASE_NAME}" \
104+
--databaseHost "$POSTGRES_HOST" \
105+
--databasePort "$POSTGRES_PORT" \
106+
--oauthGithubClientID "${(import "${pkgs.rootProjectDir}/config/ignored/github-oauth.nix").CLIENT_ID}" \
107107
'
108108
'';
109109

@@ -133,4 +133,14 @@ config.mkScripts {
133133
chromeUserDataDirPath="$chromeUserDataDirPath" \
134134
exec spago --config spago-feature-tests.dhall run --main FeatureTests.Main
135135
'';
136+
137+
dev__worker__run = config.mkCommand {} ''
138+
databaseOwnerPassword="${(import "${pkgs.rootProjectDir}/config/ignored/passwords.nix").DATABASE_OWNER_PASSWORD}" \
139+
spago --config spago-worker.dhall run --main Worker.Main --node-args '\
140+
--transportType "nodemailer-test" \
141+
--databaseName "${(import "${pkgs.rootProjectDir}/config/public/database.nix").DATABASE_NAME}" \
142+
--databaseHost "${lib.config.POSTGRES_HOST}" \
143+
--databasePort "${builtins.toString lib.config.POSTGRES_PORT}" \
144+
'
145+
'';
136146
}

migrations/0000000002-users/04_app_hidden.tables.user_emails.up.sql

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ create table app_hidden.user_emails (
66
is_verified boolean not null default false,
77

88
verification_token text check (app_hidden.biconditional_statement(is_verified = true, verification_token IS NULL)),
9-
verification_email_sent_at timestamptz check (app_hidden.biconditional_statement(is_verified = true, verification_email_sent_at IS NULL)),
10-
password_reset_email_sent_at timestamptz,
9+
10+
-- if not yet verified - null (job didnt yet sent email) or not-null (job didnt yet process email sending request)
11+
-- if verified - only null
12+
verification_email_sent_at timestamptz check (app_hidden.implication(is_verified = true, verification_email_sent_at IS NULL)),
13+
14+
-- if not verified - only null (only verified users can change password)
15+
-- if verified - null or not-null
16+
password_reset_email_sent_at timestamptz check (app_hidden.implication(is_verified = false, password_reset_email_sent_at IS NULL)),
1117

1218
created_at timestamptz not null default now(),
1319
updated_at timestamptz not null default now(),

migrations/0000000002-users/12_app_private.functions.really_create_user.up.sql

+1-5
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ begin
4747
then null
4848
else encode(gen_random_bytes(4), 'hex')
4949
end,
50-
case
51-
when email_is_verified = true
52-
then null
53-
else now()
54-
end
50+
null
5551
)
5652
returning id into v_user_email_id;
5753

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
"jsonwebtoken": "^8.5.1",
9292
"jwt-then": "^1.0.1",
9393
"material-components-web": "~8.0.0",
94+
"mjml": "^4.7.1",
95+
"nodemailer": "^6.4.16",
9496
"passport": "^0.4.1",
9597
"passport-facebook-token": "^4.0.0",
9698
"passport-github": "^1.1.0",

packages/api-server/ApiServer/Config/FromCli.purs

+8-8
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@ type CliConfig =
2626

2727
configParser :: Parser CliConfig
2828
configParser = ado
29-
exportGqlSchemaPath <- Maybe.optional $ option PathyOptparse.anyFilePosixParser $ long "export-gql-schema-path" <> metavar "ANYFILE"
30-
exportJsonSchemaPath <- Maybe.optional $ option PathyOptparse.anyFilePosixParser $ long "export-json-schema-path" <> metavar "ANYFILE"
29+
exportGqlSchemaPath <- Maybe.optional $ option PathyOptparse.anyFilePosixParser $ long "exportGqlSchemaPath" <> metavar "ANYFILE"
30+
exportJsonSchemaPath <- Maybe.optional $ option PathyOptparse.anyFilePosixParser $ long "exportJsonSchemaPath" <> metavar "ANYFILE"
3131

3232
port <- option int $ long "port" <> showDefault <> value 3000 <> metavar "INT"
33-
clientPort <- Maybe.optional $ option int $ long "client-port" <> metavar "INT"
33+
clientPort <- Maybe.optional $ option int $ long "clientPort" <> metavar "INT"
3434
hostname <- option str $ long "hostname" <> showDefault <> value "localhost" <> metavar "HOST"
3535
rootUrl <- option str $ long "rootUrl" <> showDefault <> value "http://localhost:3000" <> metavar "URL"
3636

37-
databaseName <- option str $ long "database-name" <> metavar "NAME"
38-
databaseHost <- option str $ long "database-hostname" <> metavar "NAME"
39-
databasePort <- Maybe.optional $ option int $ long "database-port" <> metavar "NAME"
37+
databaseName <- option str $ long "databaseName" <> metavar "NAME"
38+
databaseHost <- option str $ long "databaseHost" <> metavar "NAME"
39+
databasePort <- Maybe.optional $ option int $ long "databasePort" <> metavar "NAME"
4040

41-
oauthGithubClientID <- option str $ long "oauth-github-client-id" <> metavar "CLIENTID"
41+
oauthGithubClientID <- option str $ long "oauthGithubClientID" <> metavar "CLIENTID"
4242

43-
isProduction <- switch $ long "production"
43+
isProduction <- switch $ long "isProduction"
4444

4545
in
4646
{ exportGqlSchemaPath

packages/feature-tests/FeatureTests/FeatureTestSpec.purs

+9-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ withTransactionOrThrow dbConnection action = do
3333

3434
withThuncateSchemas :: a. PostgreSQL.Connection -> Aff a Aff a
3535
withThuncateSchemas dbConnection action = do
36-
PostgreSQLTruncateSchemas.truncateSchemas dbConnection ["app_public", "app_private", "app_hidden"]
36+
PostgreSQLTruncateSchemas.truncateSchemas dbConnection
37+
-- ordinary tables
38+
[ "app_public"
39+
, "app_private"
40+
, "app_hidden"
41+
-- truncate OR it will retry jobs on errors
42+
-- TODO: configure max_attempts from worker itself
43+
, "graphile_worker"
44+
]
3745
action
3846

3947
-- SpecT monadOfExample exampleConfig monadOfSpec a

packages/feature-tests/FeatureTests/Tests/Register/SuccessSpec.purs

+2
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,5 @@ spec = do
109109
) >>= \text -> text `shouldContainString` Pattern "You are on secret page"
110110

111111
-- TODO: email is received
112+
113+
pressEnterToContinue

packages/worker/Worker/Jobs/SendVerificationEmailForUserEmail.purs

+18-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import Mjml as Mjml
2525
import MjmlHalogenElements as MjmlHalogenElements
2626
import NodeMailer as NodeMailer
2727
import PostgreSQLExtra as PostgreSQLExtra
28+
import Data.Codec.Argonaut as CA
29+
import Data.Codec.Argonaut.Record as CAR
2830

2931
html
3032
:: forall w i
@@ -69,6 +71,13 @@ newtype Input = Input
6971
derive instance newtypeInput :: Newtype Input _
7072
derive instance genericInput :: Generic Input _
7173

74+
inputCodec CA.JsonCodec { id :: String }
75+
inputCodec =
76+
CA.object "Input" $
77+
CAR.record
78+
{ id: CA.string
79+
}
80+
7281
newtype UserDataFromDb
7382
= UserDataFromDb
7483
{ name :: Maybe String
@@ -109,24 +118,24 @@ job
109118
, connection
110119
, transporter
111120
} = do
112-
(input :: Input) <- genericDecodeJson json
113-
# either (throwError <<< error <<< Argonaut.printJsonDecodeError) pure
121+
input <- CA.decode inputCodec json
122+
# either (throwError <<< error <<< CA.printJsonDecodeError) pure
114123

115124
(userData :: UserDataFromDb) <-
116125
PostgreSQLExtra.queryHeadOrThrow connection
117126
( Query """
118127
SELECT
119-
t_user_email.name AS name,
128+
t_user.name AS name,
120129
t_user_email.email AS email,
121130
t_user_email.is_verified AS is_verified,
122-
t_user_email_secret.verification_token AS verification_token
123-
FROM app_public.user_emails AS t_user_email
124-
JOIN app_private.user_email_secrets AS t_user_email_secret
125-
ON t_user_email.id = t_user_email_secret.user_email_id
131+
t_user_email.verification_token AS verification_token
132+
FROM app_hidden.user_emails AS t_user_email
133+
JOIN app_public.users AS t_user
134+
ON t_user.id = t_user_email.user_id
126135
WHERE t_user_email.id = $1
127136
"""
128137
)
129-
(Row1 (unwrap input).id)
138+
(Row1 input.id)
130139

131140
emailBody <- liftEffect $
132141
Mjml.mjml2html
@@ -155,4 +164,4 @@ job
155164
WHERE t_user_email_secret.user_email_id = $1
156165
"""
157166
)
158-
(Row1 (unwrap input).id)
167+
(Row1 input.id)

schemas/schema.sql

+3-6
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,7 @@ begin
327327
then null
328328
else encode(gen_random_bytes(4), 'hex')
329329
end,
330-
case
331-
when email_is_verified = true
332-
then null
333-
else now()
334-
end
330+
null
335331
)
336332
returning id into v_user_email_id;
337333

@@ -804,7 +800,8 @@ CREATE TABLE app_hidden.user_emails (
804800
created_at timestamp with time zone DEFAULT now() NOT NULL,
805801
updated_at timestamp with time zone DEFAULT now() NOT NULL,
806802
CONSTRAINT user_emails_check CHECK (app_hidden.biconditional_statement((is_verified = true), (verification_token IS NULL))),
807-
CONSTRAINT user_emails_check1 CHECK (app_hidden.biconditional_statement((is_verified = true), (verification_email_sent_at IS NULL))),
803+
CONSTRAINT user_emails_check1 CHECK (app_hidden.implication((is_verified = true), (verification_email_sent_at IS NULL))),
804+
CONSTRAINT user_emails_check2 CHECK (app_hidden.implication((is_verified = false), (password_reset_email_sent_at IS NULL))),
808805
CONSTRAINT user_emails_email_check CHECK ((email OPERATOR(public.~) '[^@]+@[^@]+\.[^@]+'::public.citext))
809806
);
810807

spago-worker.dhall

+3
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
, sources =
55
[ "./packages/src/**/*.purs"
66
, "./packages/worker/**/*.purs"
7+
, "./packages/client/NextjsApp/AppM.purs"
8+
, "./packages/client/NextjsApp/Route.purs"
9+
, "./packages/client/NextjsApp/Link/Types.purs"
710
]
811
}

0 commit comments

Comments
 (0)