make token a bit more complex,

update go mod stuffs
This commit is contained in:
Aaron Bieber 2020-04-05 09:33:04 -06:00
parent 31af3d75d2
commit 12b72c447e
8 changed files with 98 additions and 21 deletions

View File

@ -8,7 +8,6 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/google/uuid"
_ "github.com/lib/pq" _ "github.com/lib/pq"
"suah.dev/cromp/db" "suah.dev/cromp/db"
) )
@ -33,12 +32,7 @@ func getUser(r *http.Request) (*db.User, error) {
return nil, fmt.Errorf("Unauthorized") return nil, fmt.Errorf("Unauthorized")
} }
u, err := uuid.Parse(token) user, err := base.GetUserByToken(ctx, token)
if err != nil {
return nil, err
}
user, err := base.GetUserByToken(ctx, u)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -55,6 +55,9 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
if q.similarEntriesStmt, err = db.PrepareContext(ctx, similarEntries); err != nil { if q.similarEntriesStmt, err = db.PrepareContext(ctx, similarEntries); err != nil {
return nil, fmt.Errorf("error preparing query SimilarEntries: %w", err) return nil, fmt.Errorf("error preparing query SimilarEntries: %w", err)
} }
if q.updateEntryStmt, err = db.PrepareContext(ctx, updateEntry); err != nil {
return nil, fmt.Errorf("error preparing query UpdateEntry: %w", err)
}
if q.validTokenStmt, err = db.PrepareContext(ctx, validToken); err != nil { if q.validTokenStmt, err = db.PrepareContext(ctx, validToken); err != nil {
return nil, fmt.Errorf("error preparing query ValidToken: %w", err) return nil, fmt.Errorf("error preparing query ValidToken: %w", err)
} }
@ -118,6 +121,11 @@ func (q *Queries) Close() error {
err = fmt.Errorf("error closing similarEntriesStmt: %w", cerr) err = fmt.Errorf("error closing similarEntriesStmt: %w", cerr)
} }
} }
if q.updateEntryStmt != nil {
if cerr := q.updateEntryStmt.Close(); cerr != nil {
err = fmt.Errorf("error closing updateEntryStmt: %w", cerr)
}
}
if q.validTokenStmt != nil { if q.validTokenStmt != nil {
if cerr := q.validTokenStmt.Close(); cerr != nil { if cerr := q.validTokenStmt.Close(); cerr != nil {
err = fmt.Errorf("error closing validTokenStmt: %w", cerr) err = fmt.Errorf("error closing validTokenStmt: %w", cerr)
@ -173,6 +181,7 @@ type Queries struct {
getUserStmt *sql.Stmt getUserStmt *sql.Stmt
getUserByTokenStmt *sql.Stmt getUserByTokenStmt *sql.Stmt
similarEntriesStmt *sql.Stmt similarEntriesStmt *sql.Stmt
updateEntryStmt *sql.Stmt
validTokenStmt *sql.Stmt validTokenStmt *sql.Stmt
} }
@ -191,6 +200,7 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries {
getUserStmt: q.getUserStmt, getUserStmt: q.getUserStmt,
getUserByTokenStmt: q.getUserByTokenStmt, getUserByTokenStmt: q.getUserByTokenStmt,
similarEntriesStmt: q.similarEntriesStmt, similarEntriesStmt: q.similarEntriesStmt,
updateEntryStmt: q.updateEntryStmt,
validTokenStmt: q.validTokenStmt, validTokenStmt: q.validTokenStmt,
} }
} }

View File

@ -27,6 +27,6 @@ type User struct {
Username string `json:"username"` Username string `json:"username"`
Hash string `json:"hash"` Hash string `json:"hash"`
Email string `json:"email"` Email string `json:"email"`
Token uuid.UUID `json:"token"` Token string `json:"token"`
TokenExpires time.Time `json:"token_expires"` TokenExpires time.Time `json:"token_expires"`
} }

View File

@ -33,7 +33,7 @@ type AuthUserRow struct {
LastName string `json:"last_name"` LastName string `json:"last_name"`
Username string `json:"username"` Username string `json:"username"`
Email string `json:"email"` Email string `json:"email"`
Token uuid.UUID `json:"token"` Token string `json:"token"`
TokenExpires time.Time `json:"token_expires"` TokenExpires time.Time `json:"token_expires"`
Authed bool `json:"authed"` Authed bool `json:"authed"`
} }
@ -109,7 +109,7 @@ type CreateUserParams struct {
type CreateUserRow struct { type CreateUserRow struct {
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
Username string `json:"username"` Username string `json:"username"`
Token uuid.UUID `json:"token"` Token string `json:"token"`
TokenExpires time.Time `json:"token_expires"` TokenExpires time.Time `json:"token_expires"`
} }
@ -131,14 +131,17 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
return i, err return i, err
} }
const deleteEntry = `-- name: DeleteEntry :exec const deleteEntry = `-- name: DeleteEntry :execrows
DELETE FROM entries DELETE FROM entries
WHERE entry_id = $1 WHERE entry_id = $1
` `
func (q *Queries) DeleteEntry(ctx context.Context, entryID uuid.UUID) error { func (q *Queries) DeleteEntry(ctx context.Context, entryID uuid.UUID) (int64, error) {
_, err := q.exec(ctx, q.deleteEntryStmt, deleteEntry, entryID) result, err := q.exec(ctx, q.deleteEntryStmt, deleteEntry, entryID)
return err if err != nil {
return 0, err
}
return result.RowsAffected()
} }
const deleteUser = `-- name: DeleteUser :exec const deleteUser = `-- name: DeleteUser :exec
@ -156,7 +159,7 @@ SELECT entry_id, user_id, created_at, updated_at, title, body FROM entries
WHERE user_id = (SELECT user_id FROM users WHERE token = $1 limit 1) WHERE user_id = (SELECT user_id FROM users WHERE token = $1 limit 1)
` `
func (q *Queries) EntriesByToken(ctx context.Context, token uuid.UUID) ([]Entry, error) { func (q *Queries) EntriesByToken(ctx context.Context, token string) ([]Entry, error) {
rows, err := q.query(ctx, q.entriesByTokenStmt, entriesByToken, token) rows, err := q.query(ctx, q.entriesByTokenStmt, entriesByToken, token)
if err != nil { if err != nil {
return nil, err return nil, err
@ -268,7 +271,7 @@ SELECT user_id, created_at, updated_at, first_name, last_name, username, hash, e
WHERE token = $1 LIMIT 1 WHERE token = $1 LIMIT 1
` `
func (q *Queries) GetUserByToken(ctx context.Context, token uuid.UUID) (User, error) { func (q *Queries) GetUserByToken(ctx context.Context, token string) (User, error) {
row := q.queryRow(ctx, q.getUserByTokenStmt, getUserByToken, token) row := q.queryRow(ctx, q.getUserByTokenStmt, getUserByToken, token)
var i User var i User
err := row.Scan( err := row.Scan(
@ -290,7 +293,7 @@ const similarEntries = `-- name: SimilarEntries :many
SELECT entry_id, similarity(body, $2) as similarity, SELECT entry_id, similarity(body, $2) as similarity,
ts_headline('english', body, q) as headline, ts_headline('english', body, q) as headline,
title from entries, title from entries,
plainto_tsquery($2) q to_tsquery($2) q
WHERE user_id = $1 and WHERE user_id = $1 and
similarity(body, $2) > 0.0 similarity(body, $2) > 0.0
order by similarity DESC order by similarity DESC
@ -337,12 +340,33 @@ func (q *Queries) SimilarEntries(ctx context.Context, arg SimilarEntriesParams)
return items, nil return items, nil
} }
const updateEntry = `-- name: UpdateEntry :execrows
UPDATE entries SET
title = $2,
body = $3
WHERE entry_id = $1
`
type UpdateEntryParams struct {
EntryID uuid.UUID `json:"entry_id"`
Title string `json:"title"`
Body string `json:"body"`
}
func (q *Queries) UpdateEntry(ctx context.Context, arg UpdateEntryParams) (int64, error) {
result, err := q.exec(ctx, q.updateEntryStmt, updateEntry, arg.EntryID, arg.Title, arg.Body)
if err != nil {
return 0, err
}
return result.RowsAffected()
}
const validToken = `-- name: ValidToken :one const validToken = `-- name: ValidToken :one
SELECT now() < token_created FROM users SELECT now() < token_created FROM users
WHERE token = $1 LIMIT 1 WHERE token = $1 LIMIT 1
` `
func (q *Queries) ValidToken(ctx context.Context, token uuid.UUID) (bool, error) { func (q *Queries) ValidToken(ctx context.Context, token string) (bool, error) {
row := q.queryRow(ctx, q.validTokenStmt, validToken, token) row := q.queryRow(ctx, q.validTokenStmt, validToken, token)
var column_1 bool var column_1 bool
err := row.Scan(&column_1) err := row.Scan(&column_1)

6
go.mod
View File

@ -3,7 +3,13 @@ module suah.dev/cromp
go 1.13 go 1.13
require ( require (
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/lib/pq v1.3.0 github.com/lib/pq v1.3.0
github.com/mingrammer/commonregex v1.0.1 // indirect
github.com/peterbourgon/ff/v2 v2.0.0 github.com/peterbourgon/ff/v2 v2.0.0
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8
gonum.org/v1/gonum v0.7.0 // indirect
gopkg.in/jdkato/prose.v2 v2.0.0-20190814032740-822d591a158c
gopkg.in/neurosnap/sentences.v1 v1.0.6 // indirect
) )

34
go.sum
View File

@ -1,20 +1,54 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mingrammer/commonregex v1.0.1 h1:QY0Z1Bl80jw9M3+488HJXPWnZmvtu3UdvxyodP2FTyY=
github.com/mingrammer/commonregex v1.0.1/go.mod h1:/HNZq7qReKgXBxJxce5SOxf33y0il/ZqL4Kxgo2NLcA=
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/peterbourgon/ff v1.7.0 h1:hknvTgsh90jNBIjPq7xeq32Y9AmSbpXvjrFW4sJwW+A= github.com/peterbourgon/ff v1.7.0 h1:hknvTgsh90jNBIjPq7xeq32Y9AmSbpXvjrFW4sJwW+A=
github.com/peterbourgon/ff/v2 v2.0.0 h1:lx0oYI5qr/FU1xnpNhQ+EZM04gKgn46jyYvGEEqBBbY= github.com/peterbourgon/ff/v2 v2.0.0 h1:lx0oYI5qr/FU1xnpNhQ+EZM04gKgn46jyYvGEEqBBbY=
github.com/peterbourgon/ff/v2 v2.0.0/go.mod h1:xjwr+t+SjWm4L46fcj/D+Ap+6ME7+HqFzaP22pP5Ggk= github.com/peterbourgon/ff/v2 v2.0.0/go.mod h1:xjwr+t+SjWm4L46fcj/D+Ap+6ME7+HqFzaP22pP5Ggk=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 h1:fpnn/HnJONpIu6hkXi1u/7rR0NzilgWr4T0JmWkEitk=
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw=
gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/jdkato/prose.v2 v2.0.0-20190814032740-822d591a158c h1:co085k1g+uJtaCJ8j/6HyxVtRZWI4PuhRqoIg2+WMXc=
gopkg.in/jdkato/prose.v2 v2.0.0-20190814032740-822d591a158c/go.mod h1:1uCyb8jSeRMeIfMJgVyxYssmCTAlxLBkueX+Iu2UilA=
gopkg.in/neurosnap/sentences.v1 v1.0.6 h1:v7ElyP020iEZQONyLld3fHILHWOPs+ntzuQTNPkul8E=
gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -6,6 +6,12 @@ INSERT INTO entries (
) )
RETURNING entry_id, created_at, to_tsvector(body); RETURNING entry_id, created_at, to_tsvector(body);
-- name: UpdateEntry :execrows
UPDATE entries SET
title = $2,
body = $3
WHERE entry_id = $1;
-- name: GetEntry :one -- name: GetEntry :one
SELECT * FROM entries SELECT * FROM entries
WHERE entry_id = $1 LIMIT 1; WHERE entry_id = $1 LIMIT 1;
@ -14,7 +20,7 @@ WHERE entry_id = $1 LIMIT 1;
SELECT * FROM entries SELECT * FROM entries
WHERE user_id = $1; WHERE user_id = $1;
-- name: DeleteEntry :exec -- name: DeleteEntry :execrows
DELETE FROM entries DELETE FROM entries
WHERE entry_id = $1; WHERE entry_id = $1;
@ -22,7 +28,7 @@ WHERE entry_id = $1;
SELECT entry_id, similarity(body, $2) as similarity, SELECT entry_id, similarity(body, $2) as similarity,
ts_headline('english', body, q) as headline, ts_headline('english', body, q) as headline,
title from entries, title from entries,
plainto_tsquery($2) q to_tsquery($2) q
WHERE user_id = $1 and WHERE user_id = $1 and
similarity(body, $2) > 0.0 similarity(body, $2) > 0.0
order by similarity DESC order by similarity DESC

View File

@ -13,7 +13,7 @@ CREATE TABLE users (
username text NOT NULL UNIQUE, username text NOT NULL UNIQUE,
hash text NOT NULL, hash text NOT NULL,
email text NOT NULL, email text NOT NULL,
token UUID NOT NULL default gen_random_uuid() UNIQUE, token text NOT NULL default encode(digest(gen_random_uuid()::text || now(), 'sha256'), 'hex') UNIQUE,
token_expires timestamp NOT NULL DEFAULT NOW() + INTERVAL '3 days' token_expires timestamp NOT NULL DEFAULT NOW() + INTERVAL '3 days'
); );
@ -31,3 +31,6 @@ CREATE INDEX body_trgm_idx ON entries USING gist (body gist_trgm_ops);
CREATE OR REPLACE FUNCTION hash(password text) RETURNS text AS $$ CREATE OR REPLACE FUNCTION hash(password text) RETURNS text AS $$
SELECT crypt(password, gen_salt('bf', 10)); SELECT crypt(password, gen_salt('bf', 10));
$$ LANGUAGE SQL; $$ LANGUAGE SQL;
-- CREATE OR REPLACE FUNCTION similar_entries(user_id bigserial, body text, OUT entry_id UUID, OUT similarity float, OUT headline text) AS $$
-- $$ LANGUAGE SQL;