-
Notifications
You must be signed in to change notification settings - Fork 8
/
plan
776 lines (552 loc) · 16.5 KB
/
plan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
plan
still to do:
put username into frontend modals
check if username exists and get providers for username
// Check that tips work
// Withdraw in pages
// Get reddit scraping working right
// Get bookmarklet versioning working rights
//fix dropdown and modal issues
// figure out which way to go with account linking
## Sign in checking plan
* Try to retreive user info from server
* If not signed in pop login modal - need to make it choose the right provider
* If user account and signed in account do not match, pop modal with list of accounts and merge link
## signed into both
* straight up auth
## signed into site, not signed into extension
* ask if they want to sign up for dogewand or link this social media account to an existing dogewand account
* if sign up- auth normally
* if link- type in username, get list of providers linked to username, offer them for mergeuser.
## extension and site users do not match
* ask if they want to sign up for dogewand or link this social media account to an existing dogewand account
* if sign up- auth normally
* if link- type in username, get list of providers linked to username, offer them for mergeuser.
- Not signed into site:
Pop modal informing a motherfucker, exit
- Not signed into Dogewand
Sign in button with page provider
OR
Link to existing account button
- Not signed into Dogewand
Sign in button with page provider
OR
Link to existing account button
- Signed into Dogewand with wrong acct
Link to existing account button
I have a Dogewand account linked to Twitter and Reddit. I am not logged into it.
I log into Facebook and open the extension. I get a modal asking me if I want to make a new Dogewand
account with my Facebook account or link it to another account.
page.provider: Facebook
page.uniqid: jehan.tremback
user.provider: null
user.uniqid: null
I have a Dogewand account linked to Twitter and Facebook. I am not logged into it.
I log into Facebook and open the extension. I get a modal asking me if I want to log into Dogewand
with my Facebook account.
page.provider: Facebook
page.uniqid: jehan.tremback
user.provider: null
user.uniqid: null
I do not have a Dogewand account. I am not logged into it (obviously).
I log into Facebook and open the extension. I get a modal asking me if I want to make a new Dogewand
account with my Facebook account.
page.provider: Facebook
page.uniqid: jehan.tremback
user.provider: null
user.uniqid: null
I have a Dogewand account linked to Twitter and Reddit. It has a username. I am logged into it.
I log into Facebook and open the extension. I get a modal asking me if I want to link my Facebook
account to Dogewand.
page.provider: Facebook
page.uniqid: jehan.tremback
user.provider: Facebook
user.uniqid: jehan.tremback
if (page is logged in)
if (dogewand is logged in)
if (page creds match user creds)
go!
else
if (user a exists with page creds)
message: do you want to link logged in user with user a
else
message: do you want to link logged in user with provider
else
if (user a exists with page creds)
message: do you want to log in with user a
else
message: do you want to make account with provider
else
message: please log in to provider
DROP SCHEMA public CASCADE;,
CREATE SCHEMA public;,
GRANT ALL ON SCHEMA public TO jehan;,
GRANT ALL ON SCHEMA public TO public;,
COMMENT ON SCHEMA public IS 'standard public schema';
-- populate with stuff
-- 1
INSERT INTO users (balance)
VALUES (2340);
-- 2
INSERT INTO users (balance)
VALUES (123);
-- 3
INSERT INTO users (balance)
VALUES (567);
-- 1
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (1, 'arya.stark', 'farcebook', 'Arya Stark');
-- 2
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (1, '@aryastark', 'twatter', 'Arya Stark');
-- 3
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (1, 'aryast$rk', 'yotub', 'Arya');
-- 4
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (2, 'the.hound', 'farcebook', 'The Hound');
-- 5
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (2, '@thehound', 'twatter', 'The Hound');
-- 6
INSERT INTO accounts (user_id, uniqid, provider, display_name)
VALUES (NULL, '@tywin', 'twatter', 'Tywin Lannister');
-- 1
INSERT INTO tips (tipper_id, tippee_id, amount)
VALUES (3, 4, 100);
-- 2
INSERT INTO tips (tipper_id, tippee_id, amount)
VALUES (2, 5, 10);
-- 3
INSERT INTO tips (tipper_id, tippee_id, amount)
VALUES (5, 2, 35);
-- 4
INSERT INTO tips (tipper_id, tippee_id, amount)
VALUES (1, 6, 30);
INSERT INTO deposits (txid, address, amount, blockhash)
VALUES ($1, $2, $3, $4)
INSERT INTO withdrawals (txid, amount, user_id)
VALUES ($1, $2, $3)
UPDATE users
SET balance = balance - $2
WHERE user_id = $1
SELECT user_id FROM accounts
WHERE uniqid = $1 AND provider = $2
UPDATE accounts
SET user_id = $1
WHERE user_id = $2 -- Must be authed in here, either from req.user or account supplied from passport
UPDATE users
SET balance = balance + (
SELECT balance FROM users
WHERE user_id = $2
)
WHERE user_id = $1
DELETE FROM users
WHERE user_id = $1
UPDATE users
SET balance = balance + $1
WHERE user_id = (
SELECT user_id FROM addresses
WHERE address = $2
)
BEGIN;
UPDATE accounts
SET name = $3 WHERE uniqid = $1 AND provider = $2;
INSERT INTO accounts (uniqid, provider, name)
SELECT $1, $2, $3
WHERE NOT EXISTS (
SELECT 1 FROM accounts
WHERE uniqid = $1 AND provider = $2
);
SELECT * FROM accounts
WHERE uniqid = $1 AND provider = $2;
COMMIT;
BEGIN;
UPDATE accounts
SET display_name = 'blintzen' WHERE uniqid = 'the.hound' AND provider = 'farcebook';
INSERT INTO accounts (uniqid, provider, display_name)
SELECT 'the.hound', 'farcebook', 'blintzen'
WHERE NOT EXISTS (
SELECT 1 FROM accounts
WHERE uniqid = 'the.hound' AND provider = 'farcebook'
);
SELECT * FROM accounts
WHERE uniqid = 'the.hound' AND provider = 'farcebook';
COMMIT;
-- --
-- WITH a AS (
-- UPDATE accounts
-- SET display_name = 'flintzen' WHERE uniqid = 'dingum' AND provider = 'ringum'
-- RETURNING *
-- ), b AS (
-- INSERT INTO users (balance)
-- SELECT 0
-- WHERE NOT EXISTS (
-- SELECT user_id FROM a
-- )
-- RETURNING user_id
-- ), c AS (
-- UPDATE accounts
-- SET user_id = (SELECT user_id FROM b) WHERE uniqid = 'dingum' AND provider = 'ringum'
-- RETURNING *
-- )
-- INSERT INTO accounts (uniqid, provider, display_name, user_id)
-- SELECT 'dingum', 'ringum', 'flintzen', user_id FROM b
-- WHERE NOT EXISTS (
-- SELECT 1 FROM accounts
-- WHERE uniqid = 'dingum' AND provider = 'ringum'
-- );
WITH u AS (
INSERT INTO users (balance)
VALUES (0)
RETURNING user_id
)
UPDATE accounts
SET user_id = (SELECT user_id FROM u)
WHERE account_id = $1
RETURNING user_id
SELECT * FROM users
INNER JOIN accounts ON accounts.user_id = users.user_id
WHERE users.user_id=(
SELECT user_id FROM accounts
WHERE uniqid = 'dingum' AND provider = 'ringum'
);
SELECT * FROM users
INNER JOIN accounts ON accounts.user_id = users.user_id
WHERE users.user_id=$1
-- auth
BEGIN;
INSERT INTO accounts (uniqid, provider, name)
SELECT $1, $2, $3
WHERE NOT EXISTS (
SELECT 1 FROM accounts
WHERE uniqid = $1 AND provider = $2
);
SELECT * FROM accounts
WHERE uniqid = $1 AND provider = $2;
SELECT * FROM users u, accounts a
WHERE a.user_id = u.user_id
COMMIT;
-- amount, user, uniqid, provider, name
-- example of create tip
BEGIN;
UPDATE users SET balance = balance - $2 WHERE user_id = $1;
WITH te AS (
SELECT accountInsertOrSelect($3, $4, $5) AS account_id
), tr AS (
SELECT account_id FROM accounts WHERE user_id = $1 AND provider = $4 LIMIT 1 )
INSERT INTO tips (tipper_id, tippee_id, amount)
VALUES ((SELECT account_id FROM te), (SELECT account_id from tr), $2);
RETURNING tip_id
COMMIT;
-- working resolve!
-- BEGIN;
WITH tip AS (
UPDATE tips t
SET state = CASE WHEN t.tippee_id = a.account_id THEN 'claimed'::tip_state
WHEN t.tipper_id = a.account_id THEN 'canceled'::tip_state
END
FROM accounts a WHERE user_id = $1 AND tip_id = $2 AND state = 'created'::tip_state
AND (t.tippee_id = a.account_id OR t.tipper_id = a.account_id)
RETURNING *
)
UPDATE users
SET balance = balance + (SELECT amount FROM tip)
WHERE user_id = $1
RETURNING balance
-- COMMIT;
drop function if exists accountInsertOrSelect (text, text, text);
-- uniqid, provider, name
CREATE FUNCTION accountInsertOrSelect (text, text, text)
RETURNS int
AS $$
DECLARE _id int;
BEGIN
LOOP
SELECT account_id INTO _id FROM accounts
WHERE uniqid = $1
AND provider = $2;
IF found THEN
RETURN _id;
END IF;
BEGIN
INSERT INTO accounts (uniqid, provider, display_name)
VALUES ($1, $2, $3)
RETURNING account_id INTO _id;
RETURN _id;
EXCEPTION WHEN unique_violation THEN
END;
END LOOP;
END
$$ LANGUAGE plpgsql;
drop function if exists accountInsertOrUpdate (text, text, text);
-- uniqid, provider, name
CREATE FUNCTION accountInsertOrUpdate (text, text, text)
RETURNS RECORD
AS $$
DECLARE result RECORD;
BEGIN
LOOP
UPDATE accounts
SET display_name = $3
WHERE uniqid = $1
AND provider = $2
RETURNING * INTO result;
IF found THEN
RETURN result;
END IF;
BEGIN
INSERT INTO accounts (uniqid, provider, display_name)
VALUES ($1, $2, $3)
RETURNING * INTO result;
RETURN result;
EXCEPTION WHEN unique_violation THEN
END;
END LOOP;
END
$$ LANGUAGE plpgsql;
User
balance
Account
uniqid
provider
name
user_id
Tip
amount
tipper_id
tippee_id
state
hash (maybe?)
User making scenarios:
Fresh sign up
Account making scenarios:
New tip
Linking account
Create user:
Create user with 0 balance
Find or create account with provider and uniqid and name from auth. Replace name if account
already exists.
Auth:
insert or update and select account
insert user and update account with user_id
use account.user_id to select user and join all accounts
Case 1- user is not logged in, account exists
Case 2- user is not logged in, account does not exist
Case 3- user is not logged in, account exists, is not associated with user
Merge Users:
Get provider and uniqid from auth
find account, user
move all funds from user to signed in user
change all accounts with user_id to signed in user id
Create tip:
Look for account with scraped provider and uniqid. If none found make one.
Use above for tippee_id.
tipper_id of first account from current user that matches provider (can offer choice later)
state created
insert tip
return uuid to use in url
Resolve tip:
we have:
current user_id
tip info:
tipper_id
tippee_id
get tipper_id and tippee_id accounts, check if they have user_id of current user
check if user id matches either tippee or tipper account- error if not
set state based on this- resolve or claim
move amount from escrow to user
Merging users:
User already has account with other provider(s). They receive a tip on a new provider, and are not
signed in to that provider. They claim the tip using the new user resolve flow. A new account is created.
Option 1:
Do you already have a dogewand account? Click here to merge accounts.
Need both users. NOTE: profile info is effectively same as user object.
Use passport authorize, then use profile info to look up additional account.
When you have the additional account, choose which direction to merge in.
Get balance of merge account. Move all funds from merge account to the other account.
Add auth info from merge account into other account. Delete merge account.
Want to move *to* otheraccount:
When one has accepted a tip on a new provider, creating superflous account, which one is logged into
at the time.
Want to move *from* otheraccount:
When one would like to start tipping on a new provider and is logged into the account one would like
to tip with.
Is there anything bad that happens if one merges a whole array of providers and not just one?
- Not that I can think of right now
Option 2:
Iframe comms flow:
option 1
* Loader opens iframe
* Saves reference to iframe
* Sends version to iframe
* iframe checks version, maybe pops update modal
option 2
* Loader opens Iframe
* Iframe sends hello message
* Loader saves reference to iframe
* Sends version to iframe
* iframe checks version, maybe pops update modal
TODO:
* API tests
* Automatically update balances from deposits
* Deal with remaining login jank
*
Putting whole thing in iframe-
* Load zepto twice- fuck it (maybe use native dom stuff??)
* Channel.js framework if needed? probably not right now
* Just seperate the shit out, put dom scraping stuff outside.
* Seperate lib file in iframe- like normal website
* Still concatting everything outside
Outside script functionality:
* Load and resize iframe
* Page scraping functionality
* Talk to stuff inside
* Does it need to even do any ajax???
* Be as small as possible
Iframe script functionality:
* Send resize messages
* Pop modals
* Display forms
* Send ajax or possibly just form submits?
* MVP for toolbar, balance. later, tips lists
Preprocessing needed:
Outside script:
* Concat lib stuff
* Minify
* Incremental not needed? (unless there is html or smthing?)
Iframe script:
* Same stuff from before- incremental etc.
* Put css straight in page, process seperately
How to show tip confirmation
1. Send close postmessage on submit
Pros
* Simplest
Cons
* Will need to reload tips in extension, likely race condition
2. Send post with js in iframe, send closer postmessage with data to extension
Pros
* Most elegant
Cons
* Need to write xmlhhtp requests or load zepto or other lib redundantly
3. Redirect to iframe closer page, load tip confirmation in extension upon close
Pros
* Simple
* Eliminates race condition by controlling timing
Cons
* Need to make another request
4. Submit form normally, redirect to closer page with templated-in data.
Pros
* Simple to build
Cons
* Weird
5. Submit form normally, reload page with flash message with tip data for extension.
Pros
* Existing solutions
* Flash messages will be good to have for other stuff?
Cons
* Old school?
* Reload flicker
* Need to learn new module
tip on the frontend
get username for url
or get username pasted
make tip call
display error or
display tip link
update balance and tip lists
get api/user
current logged in user data
get api/user/tips
get current user's tips
post api/tip/create_tip
create tip
post api/tip/resolve_tip
resolve tip to current user
get tip/:_id
view tip page
get account
view account of signed in user
get extension/*
pages formatted for an iframe in the extension
alternate db:
Account:
user_id
wallet_id
provider
identifier
User:
email
Tip:
from_user
to_user
amount
hash
POST dogewand.com/api/tip?id=jureto&amount=30&provider=face
generate tip
receive identifier of tipee and amount
check for user with id_info
if no user: make new user with identifier
gen wallet id
new entry in db
call jae: move to wallet
if insufficient balance: send back to extension
if success:
new tip record
extension auth:
todo:
X get gulp making js with templates
X login
X bookmarklet dom stuff
X bookmarklet loading
X bookmarklet comms
bookmarklet interface
test db api
tip page
talk to jae api
Bookmarklet interface:
popup "click on someone's profile link to tip them with the dogewand"
link for explanatory image
close button
on click on profile link:
pop amount dialog
enter amount
click tip button:
"you have tipped x y dogecoins. if they do not claim their tip, you can cancel it in 1 week. paste this message into a comment to let them know about it"
Database Schema:
user:
auth stuff etc
jae creds
tips:
amount
from_user
to_user
API calls:
new user
blah blah auth
sign in
blah blah auth
sign out
blah blah auth
generate tip
receive id_info of tipee and amount
check for user with id_info
if no user: make new user with id_info
gen wallet id
new entry in db
call jae: move to wallet
if insufficient balance: send back to extension
if success:
add tip_page record
send url back to extension
tip page
parse url for tip id
get tip record from db
gen tip page with tip amount, user etc.
view balance
call jae: get wallet balance
possible states upon viewing tip page
not signed in
"x has tipped u y doges, click here to sign in"
signed in
"x has tipped u y doges"