{"action":"created","comment":{"url":"https://api.github.com/repos/formspree/formspree/pulls/comments/207698940","pull_request_review_id":143372110,"id":207698940,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNzY5ODk0MA==","diff_hunk":"@@ -374,23 +374,96 @@ def unblock_email(email):\n         # fallback response -- should happen only when the recaptcha is failed.\n         g.log.warning('Failed to unblock email. reCaptcha test failed.')\n         return render_template('error.html',\n-                               title='Unable to unblock email',\n-                               text='Please make sure you pass the <i>reCaptcha</i> test before submitting.'), 500\n+            title='Unable to unblock email',\n+            text='Please make sure you pass the <i>reCaptcha</i> test before '\n+                 'submitting.'), 500\n \n     elif request.method == 'GET':\n         return render_template('forms/unblock_email.html', email=email), 200\n \n \n+def request_unconfirm_form(form_id):\n+    '''\n+    This endpoints triggers a confirmation email that directs users to the\n+    GET version of unconfirm_form.\n+    '''\n+    form = Form.query.get(form_id)\n+\n+    unconfirm_url = url_for(\n+        'unconfirm_form',\n+        form_id=form.id,\n+        digest=form.unconfirm_digest(),\n+        _external=True\n+    )\n+    send_email(\n+        to=form.email,\n+        subject='Unsubscribe from form at {}'.format(form.host),\n+        html=render_template_string(TEMPLATES.get('unsubscribe-confirmation.html'),\n+                                    url=unconfirm_url,\n+                                    email=form.email,\n+                                    host=form.host),\n+        text=render_template('email/unsubscribe-confirmation.txt',\n+            url=unconfirm_url,\n+            email=form.email,\n+            host=form.host),\n+        sender=settings.DEFAULT_SENDER,\n+    )\n+\n+    return render_template('info.html',\n+        title='Link sent to your address',\n+        text=\"To prevent unwanted form submission losses, we've sent the link \"\n+             \"to finish the unsubscription to {}\".format(form.email)), 200\n+    \n+\n def unconfirm_form(form_id, digest):\n     '''\n-    We send a digest as the List-Unsubscribe header on every submission.\n-    Here we get that digest and handle the unconfirmation request.\n+    Here we check the digest for a form and handle the unconfirmation.\n+    Also works for List-Unsubscribe triggered POSTs.\n+    When GET, give the user the option to unsubscribe from other forms as well.\n     '''\n     form = Form.query.get(form_id)\n-    if form.unconfirm_with_digest(digest):\n-        return '', 200\n-    else:\n-        return abort(401)\n+    success = form.unconfirm_with_digest(digest)\n+\n+    if request.method == 'GET':\n+        if success:\n+            other_forms = Form.query.filter_by(confirmed=True, email=form.email)\n+\n+            session['unconfirming'] = form.email\n+\n+            return render_template('forms/unconfirm.html',\n+                other_forms=other_forms,\n+                disabled_form=form\n+            ), 200\n+        else:\n+            return render_template('error.html',\n+                title='Not a valid link',\n+                text='This unconfirmation link is not valid.'), 400\n+\n+    if request.method == 'POST':\n+        if success:\n+            return '', 200\n+        else:\n+            return abort(401)\n+\n+\n+def unconfirm_multiple():\n+    unconfirming_for_email = session.get('unconfirming')\n+    if not unconfirming_for_email:","path":"formspree/forms/views.py","position":106,"original_position":106,"commit_id":"308d252cf8dbb9878ba31dc07b764d088ef452a2","original_commit_id":"308d252cf8dbb9878ba31dc07b764d088ef452a2","user":{"login":"rohitdatta","id":6260066,"node_id":"MDQ6VXNlcjYyNjAwNjY=","avatar_url":"https://avatars2.githubusercontent.com/u/6260066?v=4","gravatar_id":"","url":"https://api.github.com/users/rohitdatta","html_url":"https://github.com/rohitdatta","followers_url":"https://api.github.com/users/rohitdatta/followers","following_url":"https://api.github.com/users/rohitdatta/following{/other_user}","gists_url":"https://api.github.com/users/rohitdatta/gists{/gist_id}","starred_url":"https://api.github.com/users/rohitdatta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rohitdatta/subscriptions","organizations_url":"https://api.github.com/users/rohitdatta/orgs","repos_url":"https://api.github.com/users/rohitdatta/repos","events_url":"https://api.github.com/users/rohitdatta/events{/privacy}","received_events_url":"https://api.github.com/users/rohitdatta/received_events","type":"User","site_admin":false},"body":"Isn't this insecure because someone could just imitate the cookies?","created_at":"2018-08-04T03:47:52Z","updated_at":"2018-08-04T03:47:52Z","html_url":"https://github.com/formspree/formspree/pull/188#discussion_r207698940","pull_request_url":"https://api.github.com/repos/formspree/formspree/pulls/188","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/formspree/formspree/pulls/comments/207698940"},"html":{"href":"https://github.com/formspree/formspree/pull/188#discussion_r207698940"},"pull_request":{"href":"https://api.github.com/repos/formspree/formspree/pulls/188"}}},"pull_request":{"url":"https://api.github.com/repos/formspree/formspree/pulls/188","id":204673830,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA0NjczODMw","html_url":"https://github.com/formspree/formspree/pull/188","diff_url":"https://github.com/formspree/formspree/pull/188.diff","patch_url":"https://github.com/formspree/formspree/pull/188.patch","issue_url":"https://api.github.com/repos/formspree/formspree/issues/188","number":188,"state":"open","locked":false,"title":"unconfirm/unsubscribe from forms.","user":{"login":"fiatjaf","id":1653275,"node_id":"MDQ6VXNlcjE2NTMyNzU=","avatar_url":"https://avatars1.githubusercontent.com/u/1653275?v=4","gravatar_id":"","url":"https://api.github.com/users/fiatjaf","html_url":"https://github.com/fiatjaf","followers_url":"https://api.github.com/users/fiatjaf/followers","following_url":"https://api.github.com/users/fiatjaf/following{/other_user}","gists_url":"https://api.github.com/users/fiatjaf/gists{/gist_id}","starred_url":"https://api.github.com/users/fiatjaf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fiatjaf/subscriptions","organizations_url":"https://api.github.com/users/fiatjaf/orgs","repos_url":"https://api.github.com/users/fiatjaf/repos","events_url":"https://api.github.com/users/fiatjaf/events{/privacy}","received_events_url":"https://api.github.com/users/fiatjaf/received_events","type":"User","site_admin":false},"body":"Supersedes https://github.com/formspree/formspree/pull/122.\r\n\r\nSee commit comments.\r\n\r\n![2018-07-29-215351_624x138_scrot](https://user-images.githubusercontent.com/1653275/43373126-fd930e6a-937d-11e8-9de3-f27e1714710b.png)\r\n![2018-07-29-220953_834x651_scrot](https://user-images.githubusercontent.com/1653275/43373123-fcf0e5d6-937d-11e8-8504-c0fd0359275e.png)\r\n![2018-07-29-215328_734x296_scrot](https://user-images.githubusercontent.com/1653275/43373127-fdb9a462-937d-11e8-8412-a27d9fc68c23.png)\r\n![2018-07-29-220358_777x791_scrot](https://user-images.githubusercontent.com/1653275/43373125-fd68240c-937d-11e8-9774-60f50759d91f.png)\r\n![2018-07-29-221027_858x819_scrot](https://user-images.githubusercontent.com/1653275/43373122-fccadbfc-937d-11e8-8b5f-f49721be7fae.png)\r\n![2018-07-29-220448_833x516_scrot](https://user-images.githubusercontent.com/1653275/43373124-fd28f638-937d-11e8-9702-b38a2fb44de9.png)\r\n","created_at":"2018-07-30T01:25:44Z","updated_at":"2018-08-04T03:47:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"43df1e8daf310a1de047fd5db4384267d2d0a2c2","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/formspree/formspree/pulls/188/commits","review_comments_url":"https://api.github.com/repos/formspree/formspree/pulls/188/comments","review_comment_url":"https://api.github.com/repos/formspree/formspree/pulls/comments{/number}","comments_url":"https://api.github.com/repos/formspree/formspree/issues/188/comments","statuses_url":"https://api.github.com/repos/formspree/formspree/statuses/308d252cf8dbb9878ba31dc07b764d088ef452a2","head":{"label":"fiatjaf:unconfirm-forms-2","ref":"unconfirm-forms-2","sha":"308d252cf8dbb9878ba31dc07b764d088ef452a2","user":{"login":"fiatjaf","id":1653275,"node_id":"MDQ6VXNlcjE2NTMyNzU=","avatar_url":"https://avatars1.githubusercontent.com/u/1653275?v=4","gravatar_id":"","url":"https://api.github.com/users/fiatjaf","html_url":"https://github.com/fiatjaf","followers_url":"https://api.github.com/users/fiatjaf/followers","following_url":"https://api.github.com/users/fiatjaf/following{/other_user}","gists_url":"https://api.github.com/users/fiatjaf/gists{/gist_id}","starred_url":"https://api.github.com/users/fiatjaf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fiatjaf/subscriptions","organizations_url":"https://api.github.com/users/fiatjaf/orgs","repos_url":"https://api.github.com/users/fiatjaf/repos","events_url":"https://api.github.com/users/fiatjaf/events{/privacy}","received_events_url":"https://api.github.com/users/fiatjaf/received_events","type":"User","site_admin":false},"repo":{"id":28492157,"node_id":"MDEwOlJlcG9zaXRvcnkyODQ5MjE1Nw==","name":"formspree","full_name":"fiatjaf/formspree","owner":{"login":"fiatjaf","id":1653275,"node_id":"MDQ6VXNlcjE2NTMyNzU=","avatar_url":"https://avatars1.githubusercontent.com/u/1653275?v=4","gravatar_id":"","url":"https://api.github.com/users/fiatjaf","html_url":"https://github.com/fiatjaf","followers_url":"https://api.github.com/users/fiatjaf/followers","following_url":"https://api.github.com/users/fiatjaf/following{/other_user}","gists_url":"https://api.github.com/users/fiatjaf/gists{/gist_id}","starred_url":"https://api.github.com/users/fiatjaf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fiatjaf/subscriptions","organizations_url":"https://api.github.com/users/fiatjaf/orgs","repos_url":"https://api.github.com/users/fiatjaf/repos","events_url":"https://api.github.com/users/fiatjaf/events{/privacy}","received_events_url":"https://api.github.com/users/fiatjaf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fiatjaf/formspree","description":null,"fork":true,"url":"https://api.github.com/repos/fiatjaf/formspree","forks_url":"https://api.github.com/repos/fiatjaf/formspree/forks","keys_url":"https://api.github.com/repos/fiatjaf/formspree/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fiatjaf/formspree/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fiatjaf/formspree/teams","hooks_url":"https://api.github.com/repos/fiatjaf/formspree/hooks","issue_events_url":"https://api.github.com/repos/fiatjaf/formspree/issues/events{/number}","events_url":"https://api.github.com/repos/fiatjaf/formspree/events","assignees_url":"https://api.github.com/repos/fiatjaf/formspree/assignees{/user}","branches_url":"https://api.github.com/repos/fiatjaf/formspree/branches{/branch}","tags_url":"https://api.github.com/repos/fiatjaf/formspree/tags","blobs_url":"https://api.github.com/repos/fiatjaf/formspree/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fiatjaf/formspree/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fiatjaf/formspree/git/refs{/sha}","trees_url":"https://api.github.com/repos/fiatjaf/formspree/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fiatjaf/formspree/statuses/{sha}","languages_url":"https://api.github.com/repos/fiatjaf/formspree/languages","stargazers_url":"https://api.github.com/repos/fiatjaf/formspree/stargazers","contributors_url":"https://api.github.com/repos/fiatjaf/formspree/contributors","subscribers_url":"https://api.github.com/repos/fiatjaf/formspree/subscribers","subscription_url":"https://api.github.com/repos/fiatjaf/formspree/subscription","commits_url":"https://api.github.com/repos/fiatjaf/formspree/commits{/sha}","git_commits_url":"https://api.github.com/repos/fiatjaf/formspree/git/commits{/sha}","comments_url":"https://api.github.com/repos/fiatjaf/formspree/comments{/number}","issue_comment_url":"https://api.github.com/repos/fiatjaf/formspree/issues/comments{/number}","contents_url":"https://api.github.com/repos/fiatjaf/formspree/contents/{+path}","compare_url":"https://api.github.com/repos/fiatjaf/formspree/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fiatjaf/formspree/merges","archive_url":"https://api.github.com/repos/fiatjaf/formspree/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fiatjaf/formspree/downloads","issues_url":"https://api.github.com/repos/fiatjaf/formspree/issues{/number}","pulls_url":"https://api.github.com/repos/fiatjaf/formspree/pulls{/number}","milestones_url":"https://api.github.com/repos/fiatjaf/formspree/milestones{/number}","notifications_url":"https://api.github.com/repos/fiatjaf/formspree/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fiatjaf/formspree/labels{/name}","releases_url":"https://api.github.com/repos/fiatjaf/formspree/releases{/id}","deployments_url":"https://api.github.com/repos/fiatjaf/formspree/deployments","created_at":"2014-12-25T21:57:31Z","updated_at":"2018-05-14T00:51:01Z","pushed_at":"2018-08-04T00:33:55Z","git_url":"git://github.com/fiatjaf/formspree.git","ssh_url":"git@github.com:fiatjaf/formspree.git","clone_url":"https://github.com/fiatjaf/formspree.git","svn_url":"https://github.com/fiatjaf/formspree","homepage":null,"size":2807,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"formspree:master","ref":"master","sha":"0d869f117771a9e0244928f034560e9a2ec4a81d","user":{"login":"formspree","id":14319378,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MzE5Mzc4","avatar_url":"https://avatars2.githubusercontent.com/u/14319378?v=4","gravatar_id":"","url":"https://api.github.com/users/formspree","html_url":"https://github.com/formspree","followers_url":"https://api.github.com/users/formspree/followers","following_url":"https://api.github.com/users/formspree/following{/other_user}","gists_url":"https://api.github.com/users/formspree/gists{/gist_id}","starred_url":"https://api.github.com/users/formspree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/formspree/subscriptions","organizations_url":"https://api.github.com/users/formspree/orgs","repos_url":"https://api.github.com/users/formspree/repos","events_url":"https://api.github.com/users/formspree/events{/privacy}","received_events_url":"https://api.github.com/users/formspree/received_events","type":"Organization","site_admin":false},"repo":{"id":27942236,"node_id":"MDEwOlJlcG9zaXRvcnkyNzk0MjIzNg==","name":"formspree","full_name":"formspree/formspree","owner":{"login":"formspree","id":14319378,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MzE5Mzc4","avatar_url":"https://avatars2.githubusercontent.com/u/14319378?v=4","gravatar_id":"","url":"https://api.github.com/users/formspree","html_url":"https://github.com/formspree","followers_url":"https://api.github.com/users/formspree/followers","following_url":"https://api.github.com/users/formspree/following{/other_user}","gists_url":"https://api.github.com/users/formspree/gists{/gist_id}","starred_url":"https://api.github.com/users/formspree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/formspree/subscriptions","organizations_url":"https://api.github.com/users/formspree/orgs","repos_url":"https://api.github.com/users/formspree/repos","events_url":"https://api.github.com/users/formspree/events{/privacy}","received_events_url":"https://api.github.com/users/formspree/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/formspree/formspree","description":"Easy HTML form without PHP or JavaScript","fork":false,"url":"https://api.github.com/repos/formspree/formspree","forks_url":"https://api.github.com/repos/formspree/formspree/forks","keys_url":"https://api.github.com/repos/formspree/formspree/keys{/key_id}","collaborators_url":"https://api.github.com/repos/formspree/formspree/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/formspree/formspree/teams","hooks_url":"https://api.github.com/repos/formspree/formspree/hooks","issue_events_url":"https://api.github.com/repos/formspree/formspree/issues/events{/number}","events_url":"https://api.github.com/repos/formspree/formspree/events","assignees_url":"https://api.github.com/repos/formspree/formspree/assignees{/user}","branches_url":"https://api.github.com/repos/formspree/formspree/branches{/branch}","tags_url":"https://api.github.com/repos/formspree/formspree/tags","blobs_url":"https://api.github.com/repos/formspree/formspree/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/formspree/formspree/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/formspree/formspree/git/refs{/sha}","trees_url":"https://api.github.com/repos/formspree/formspree/git/trees{/sha}","statuses_url":"https://api.github.com/repos/formspree/formspree/statuses/{sha}","languages_url":"https://api.github.com/repos/formspree/formspree/languages","stargazers_url":"https://api.github.com/repos/formspree/formspree/stargazers","contributors_url":"https://api.github.com/repos/formspree/formspree/contributors","subscribers_url":"https://api.github.com/repos/formspree/formspree/subscribers","subscription_url":"https://api.github.com/repos/formspree/formspree/subscription","commits_url":"https://api.github.com/repos/formspree/formspree/commits{/sha}","git_commits_url":"https://api.github.com/repos/formspree/formspree/git/commits{/sha}","comments_url":"https://api.github.com/repos/formspree/formspree/comments{/number}","issue_comment_url":"https://api.github.com/repos/formspree/formspree/issues/comments{/number}","contents_url":"https://api.github.com/repos/formspree/formspree/contents/{+path}","compare_url":"https://api.github.com/repos/formspree/formspree/compare/{base}...{head}","merges_url":"https://api.github.com/repos/formspree/formspree/merges","archive_url":"https://api.github.com/repos/formspree/formspree/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/formspree/formspree/downloads","issues_url":"https://api.github.com/repos/formspree/formspree/issues{/number}","pulls_url":"https://api.github.com/repos/formspree/formspree/pulls{/number}","milestones_url":"https://api.github.com/repos/formspree/formspree/milestones{/number}","notifications_url":"https://api.github.com/repos/formspree/formspree/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/formspree/formspree/labels{/name}","releases_url":"https://api.github.com/repos/formspree/formspree/releases{/id}","deployments_url":"https://api.github.com/repos/formspree/formspree/deployments","created_at":"2014-12-12T23:20:09Z","updated_at":"2018-08-03T01:41:08Z","pushed_at":"2018-08-04T00:33:56Z","git_url":"git://github.com/formspree/formspree.git","ssh_url":"git@github.com:formspree/formspree.git","clone_url":"https://github.com/formspree/formspree.git","svn_url":"https://github.com/formspree/formspree","homepage":"https://formspree.io","size":2714,"stargazers_count":2224,"watchers_count":2224,"language":"CSS","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":183,"mirror_url":null,"archived":false,"open_issues_count":14,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":183,"open_issues":14,"watchers":2224,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/formspree/formspree/pulls/188"},"html":{"href":"https://github.com/formspree/formspree/pull/188"},"issue":{"href":"https://api.github.com/repos/formspree/formspree/issues/188"},"comments":{"href":"https://api.github.com/repos/formspree/formspree/issues/188/comments"},"review_comments":{"href":"https://api.github.com/repos/formspree/formspree/pulls/188/comments"},"review_comment":{"href":"https://api.github.com/repos/formspree/formspree/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/formspree/formspree/pulls/188/commits"},"statuses":{"href":"https://api.github.com/repos/formspree/formspree/statuses/308d252cf8dbb9878ba31dc07b764d088ef452a2"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"rohitdatta"}}