{"action":"created","comment":{"url":"https://api.github.com/repos/observable-universe/miner/pulls/comments/107070374","pull_request_review_id":28019595,"id":107070374,"diff_hunk":"@@ -0,0 +1,97 @@\n+<?php\n+\n+namespace App\\Http\\Controllers;\n+\n+use Illuminate\\Http\\Request;\n+use Illuminate\\Support\\Facades\\Cache;\n+use Laravel\\Lumen\\Routing\\Controller as BaseController;\n+use Lcobucci\\JWT\\Builder;\n+use Lcobucci\\JWT\\Parser;\n+use Lcobucci\\JWT\\Signer\\Hmac\\Sha256;\n+use Miner\\Auth\\Entities\\User;\n+use Miner\\Auth\\Repositories\\UserRepository;\n+use Miner\\Auth\\Entities\\Uuid;\n+\n+class AuthController extends BaseController\n+{\n+    public function login(Request $request, UserRepository $userRepository, Cache $cache)\n+    {\n+        $this->validate($request, [\n+            'username' => 'required',\n+            'password' => 'required'\n+        ]);\n+\n+        $email = $request->get('email');\n+        $password = $request->get('password');\n+\n+        $user = $userRepository->findByEmail($email);\n+\n+        // use php 5.5 password_hash/password_verify magix to validate the password matches\n+        if(!password_verify($password, $user->getPasswordHash())) {\n+            throw new \\Exception('invalid password');\n+        }\n+\n+        $accessToken = (string)$this->generateAccessToken($user);\n+\n+        // generate a new unique id for our token\n+        $uuid = new Uuid();\n+\n+        // get all refresh tokens for this user based on the\n+        $refreshTokens = json_decode($cache->get($user->getCacheKey()));\n+        $refreshTokens[] = $uuid->toString();\n+\n+        // get rid of the oldest token to make room for the new token\n+        if(count($refreshTokens) >= 10) {\n+            array_shift($refreshTokens);\n+        }\n+\n+        // add the new token to cache\n+        $cache->set($user->getCacheKey(), json_encode($refreshTokens));\n+\n+        return response()->json(['accessToken' => $accessToken, 'refreshToken' => $uuid->toString()]);\n+    }\n+\n+    public function refresh(Request $request, UserRepository $userRepository, Cache $cache)\n+    {\n+        $this->validate($request, [\n+            'accessToken' => 'required',\n+            'refreshToken' => 'required'\n+        ]);\n+\n+        // convert our request to a jwt token\n+        $token = (new Parser())->parse($request->get('accessToken'));\n+\n+        // verify the password jwt token and make sure its signature checks out with its content\n+        // we need the token to prove that this user once authenticated using /login\n+        if(!$token->verify(new Sha256(), 'secret')) {\n+            throw new \\Exception('invalid access token');\n+        }\n+\n+        $user = $userRepository->findById($token->getClaim('userId'));\n+\n+        // check for existence for this users refresh tokens\n+        $refreshTokens = json_decode($cache->get($user->getCacheKey()));\n+        if(!in_array($request->get('refreshToken'), $refreshTokens)) {\n+            throw new \\Exception('invalid refresh token');\n+        }\n+\n+        // generate a new access token, fuck yah!\n+        $accessToken = (string)$this->generateAccessToken($user);\n+\n+        return response()->json(['accessToken' => $accessToken]);\n+    }\n+\n+    private function generateAccessToken(User $user)\n+    {\n+        $token = (new Builder())->setIssuer('http://auth.miner.com') // Configures the issuer (iss claim)\n+            ->setAudience('http://miner.com') // Configures the audience (aud claim)\n+            ->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)\n+            ->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)","path":"auth/app/Http/Controllers/AuthController.php","position":89,"original_position":89,"commit_id":"bce4478891761d0ca41205ce4b4a04898fa1f4b8","original_commit_id":"bce4478891761d0ca41205ce4b4a04898fa1f4b8","user":{"login":"HeathNaylor","id":10814256,"avatar_url":"https://avatars3.githubusercontent.com/u/10814256?v=3","gravatar_id":"","url":"https://api.github.com/users/HeathNaylor","html_url":"https://github.com/HeathNaylor","followers_url":"https://api.github.com/users/HeathNaylor/followers","following_url":"https://api.github.com/users/HeathNaylor/following{/other_user}","gists_url":"https://api.github.com/users/HeathNaylor/gists{/gist_id}","starred_url":"https://api.github.com/users/HeathNaylor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HeathNaylor/subscriptions","organizations_url":"https://api.github.com/users/HeathNaylor/orgs","repos_url":"https://api.github.com/users/HeathNaylor/repos","events_url":"https://api.github.com/users/HeathNaylor/events{/privacy}","received_events_url":"https://api.github.com/users/HeathNaylor/received_events","type":"User","site_admin":false},"body":"Would like to see 3600 as either a member property or an application constant and call it `ONE_HOUR_IN_SECONDS` or `ONE_HOUR` or something similar.","created_at":"2017-03-21T04:21:11Z","updated_at":"2017-03-21T04:30:51Z","html_url":"https://github.com/observable-universe/miner/pull/9#discussion_r107070374","pull_request_url":"https://api.github.com/repos/observable-universe/miner/pulls/9","_links":{"self":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/comments/107070374"},"html":{"href":"https://github.com/observable-universe/miner/pull/9#discussion_r107070374"},"pull_request":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/9"}}},"pull_request":{"url":"https://api.github.com/repos/observable-universe/miner/pulls/9","id":109843373,"html_url":"https://github.com/observable-universe/miner/pull/9","diff_url":"https://github.com/observable-universe/miner/pull/9.diff","patch_url":"https://github.com/observable-universe/miner/pull/9.patch","issue_url":"https://api.github.com/repos/observable-universe/miner/issues/9","number":9,"state":"open","locked":false,"title":"Authentication service foundation","user":{"login":"rreynier","id":1953114,"avatar_url":"https://avatars3.githubusercontent.com/u/1953114?v=3","gravatar_id":"","url":"https://api.github.com/users/rreynier","html_url":"https://github.com/rreynier","followers_url":"https://api.github.com/users/rreynier/followers","following_url":"https://api.github.com/users/rreynier/following{/other_user}","gists_url":"https://api.github.com/users/rreynier/gists{/gist_id}","starred_url":"https://api.github.com/users/rreynier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rreynier/subscriptions","organizations_url":"https://api.github.com/users/rreynier/orgs","repos_url":"https://api.github.com/users/rreynier/repos","events_url":"https://api.github.com/users/rreynier/events{/privacy}","received_events_url":"https://api.github.com/users/rreynier/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-03-09T05:31:18Z","updated_at":"2017-03-21T04:30:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"432fb74994ad1e8a50bd98bc157b1f2b6ef060e7","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/observable-universe/miner/pulls/9/commits","review_comments_url":"https://api.github.com/repos/observable-universe/miner/pulls/9/comments","review_comment_url":"https://api.github.com/repos/observable-universe/miner/pulls/comments{/number}","comments_url":"https://api.github.com/repos/observable-universe/miner/issues/9/comments","statuses_url":"https://api.github.com/repos/observable-universe/miner/statuses/bce4478891761d0ca41205ce4b4a04898fa1f4b8","head":{"label":"observable-universe:authentication-service","ref":"authentication-service","sha":"bce4478891761d0ca41205ce4b4a04898fa1f4b8","user":{"login":"observable-universe","id":25024210,"avatar_url":"https://avatars2.githubusercontent.com/u/25024210?v=3","gravatar_id":"","url":"https://api.github.com/users/observable-universe","html_url":"https://github.com/observable-universe","followers_url":"https://api.github.com/users/observable-universe/followers","following_url":"https://api.github.com/users/observable-universe/following{/other_user}","gists_url":"https://api.github.com/users/observable-universe/gists{/gist_id}","starred_url":"https://api.github.com/users/observable-universe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/observable-universe/subscriptions","organizations_url":"https://api.github.com/users/observable-universe/orgs","repos_url":"https://api.github.com/users/observable-universe/repos","events_url":"https://api.github.com/users/observable-universe/events{/privacy}","received_events_url":"https://api.github.com/users/observable-universe/received_events","type":"Organization","site_admin":false},"repo":{"id":78497921,"name":"miner","full_name":"observable-universe/miner","owner":{"login":"observable-universe","id":25024210,"avatar_url":"https://avatars2.githubusercontent.com/u/25024210?v=3","gravatar_id":"","url":"https://api.github.com/users/observable-universe","html_url":"https://github.com/observable-universe","followers_url":"https://api.github.com/users/observable-universe/followers","following_url":"https://api.github.com/users/observable-universe/following{/other_user}","gists_url":"https://api.github.com/users/observable-universe/gists{/gist_id}","starred_url":"https://api.github.com/users/observable-universe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/observable-universe/subscriptions","organizations_url":"https://api.github.com/users/observable-universe/orgs","repos_url":"https://api.github.com/users/observable-universe/repos","events_url":"https://api.github.com/users/observable-universe/events{/privacy}","received_events_url":"https://api.github.com/users/observable-universe/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/observable-universe/miner","description":null,"fork":false,"url":"https://api.github.com/repos/observable-universe/miner","forks_url":"https://api.github.com/repos/observable-universe/miner/forks","keys_url":"https://api.github.com/repos/observable-universe/miner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/observable-universe/miner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/observable-universe/miner/teams","hooks_url":"https://api.github.com/repos/observable-universe/miner/hooks","issue_events_url":"https://api.github.com/repos/observable-universe/miner/issues/events{/number}","events_url":"https://api.github.com/repos/observable-universe/miner/events","assignees_url":"https://api.github.com/repos/observable-universe/miner/assignees{/user}","branches_url":"https://api.github.com/repos/observable-universe/miner/branches{/branch}","tags_url":"https://api.github.com/repos/observable-universe/miner/tags","blobs_url":"https://api.github.com/repos/observable-universe/miner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/observable-universe/miner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/observable-universe/miner/git/refs{/sha}","trees_url":"https://api.github.com/repos/observable-universe/miner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/observable-universe/miner/statuses/{sha}","languages_url":"https://api.github.com/repos/observable-universe/miner/languages","stargazers_url":"https://api.github.com/repos/observable-universe/miner/stargazers","contributors_url":"https://api.github.com/repos/observable-universe/miner/contributors","subscribers_url":"https://api.github.com/repos/observable-universe/miner/subscribers","subscription_url":"https://api.github.com/repos/observable-universe/miner/subscription","commits_url":"https://api.github.com/repos/observable-universe/miner/commits{/sha}","git_commits_url":"https://api.github.com/repos/observable-universe/miner/git/commits{/sha}","comments_url":"https://api.github.com/repos/observable-universe/miner/comments{/number}","issue_comment_url":"https://api.github.com/repos/observable-universe/miner/issues/comments{/number}","contents_url":"https://api.github.com/repos/observable-universe/miner/contents/{+path}","compare_url":"https://api.github.com/repos/observable-universe/miner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/observable-universe/miner/merges","archive_url":"https://api.github.com/repos/observable-universe/miner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/observable-universe/miner/downloads","issues_url":"https://api.github.com/repos/observable-universe/miner/issues{/number}","pulls_url":"https://api.github.com/repos/observable-universe/miner/pulls{/number}","milestones_url":"https://api.github.com/repos/observable-universe/miner/milestones{/number}","notifications_url":"https://api.github.com/repos/observable-universe/miner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/observable-universe/miner/labels{/name}","releases_url":"https://api.github.com/repos/observable-universe/miner/releases{/id}","deployments_url":"https://api.github.com/repos/observable-universe/miner/deployments","created_at":"2017-01-10T04:35:37Z","updated_at":"2017-03-09T06:09:19Z","pushed_at":"2017-03-21T04:16:02Z","git_url":"git://github.com/observable-universe/miner.git","ssh_url":"git@github.com:observable-universe/miner.git","clone_url":"https://github.com/observable-universe/miner.git","svn_url":"https://github.com/observable-universe/miner","homepage":null,"size":245,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":9,"forks":0,"open_issues":9,"watchers":0,"default_branch":"master"}},"base":{"label":"observable-universe:master","ref":"master","sha":"6723a6895ac63487789a37f71cea990e04530466","user":{"login":"observable-universe","id":25024210,"avatar_url":"https://avatars2.githubusercontent.com/u/25024210?v=3","gravatar_id":"","url":"https://api.github.com/users/observable-universe","html_url":"https://github.com/observable-universe","followers_url":"https://api.github.com/users/observable-universe/followers","following_url":"https://api.github.com/users/observable-universe/following{/other_user}","gists_url":"https://api.github.com/users/observable-universe/gists{/gist_id}","starred_url":"https://api.github.com/users/observable-universe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/observable-universe/subscriptions","organizations_url":"https://api.github.com/users/observable-universe/orgs","repos_url":"https://api.github.com/users/observable-universe/repos","events_url":"https://api.github.com/users/observable-universe/events{/privacy}","received_events_url":"https://api.github.com/users/observable-universe/received_events","type":"Organization","site_admin":false},"repo":{"id":78497921,"name":"miner","full_name":"observable-universe/miner","owner":{"login":"observable-universe","id":25024210,"avatar_url":"https://avatars2.githubusercontent.com/u/25024210?v=3","gravatar_id":"","url":"https://api.github.com/users/observable-universe","html_url":"https://github.com/observable-universe","followers_url":"https://api.github.com/users/observable-universe/followers","following_url":"https://api.github.com/users/observable-universe/following{/other_user}","gists_url":"https://api.github.com/users/observable-universe/gists{/gist_id}","starred_url":"https://api.github.com/users/observable-universe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/observable-universe/subscriptions","organizations_url":"https://api.github.com/users/observable-universe/orgs","repos_url":"https://api.github.com/users/observable-universe/repos","events_url":"https://api.github.com/users/observable-universe/events{/privacy}","received_events_url":"https://api.github.com/users/observable-universe/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/observable-universe/miner","description":null,"fork":false,"url":"https://api.github.com/repos/observable-universe/miner","forks_url":"https://api.github.com/repos/observable-universe/miner/forks","keys_url":"https://api.github.com/repos/observable-universe/miner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/observable-universe/miner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/observable-universe/miner/teams","hooks_url":"https://api.github.com/repos/observable-universe/miner/hooks","issue_events_url":"https://api.github.com/repos/observable-universe/miner/issues/events{/number}","events_url":"https://api.github.com/repos/observable-universe/miner/events","assignees_url":"https://api.github.com/repos/observable-universe/miner/assignees{/user}","branches_url":"https://api.github.com/repos/observable-universe/miner/branches{/branch}","tags_url":"https://api.github.com/repos/observable-universe/miner/tags","blobs_url":"https://api.github.com/repos/observable-universe/miner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/observable-universe/miner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/observable-universe/miner/git/refs{/sha}","trees_url":"https://api.github.com/repos/observable-universe/miner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/observable-universe/miner/statuses/{sha}","languages_url":"https://api.github.com/repos/observable-universe/miner/languages","stargazers_url":"https://api.github.com/repos/observable-universe/miner/stargazers","contributors_url":"https://api.github.com/repos/observable-universe/miner/contributors","subscribers_url":"https://api.github.com/repos/observable-universe/miner/subscribers","subscription_url":"https://api.github.com/repos/observable-universe/miner/subscription","commits_url":"https://api.github.com/repos/observable-universe/miner/commits{/sha}","git_commits_url":"https://api.github.com/repos/observable-universe/miner/git/commits{/sha}","comments_url":"https://api.github.com/repos/observable-universe/miner/comments{/number}","issue_comment_url":"https://api.github.com/repos/observable-universe/miner/issues/comments{/number}","contents_url":"https://api.github.com/repos/observable-universe/miner/contents/{+path}","compare_url":"https://api.github.com/repos/observable-universe/miner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/observable-universe/miner/merges","archive_url":"https://api.github.com/repos/observable-universe/miner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/observable-universe/miner/downloads","issues_url":"https://api.github.com/repos/observable-universe/miner/issues{/number}","pulls_url":"https://api.github.com/repos/observable-universe/miner/pulls{/number}","milestones_url":"https://api.github.com/repos/observable-universe/miner/milestones{/number}","notifications_url":"https://api.github.com/repos/observable-universe/miner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/observable-universe/miner/labels{/name}","releases_url":"https://api.github.com/repos/observable-universe/miner/releases{/id}","deployments_url":"https://api.github.com/repos/observable-universe/miner/deployments","created_at":"2017-01-10T04:35:37Z","updated_at":"2017-03-09T06:09:19Z","pushed_at":"2017-03-21T04:16:02Z","git_url":"git://github.com/observable-universe/miner.git","ssh_url":"git@github.com:observable-universe/miner.git","clone_url":"https://github.com/observable-universe/miner.git","svn_url":"https://github.com/observable-universe/miner","homepage":null,"size":245,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":9,"forks":0,"open_issues":9,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/9"},"html":{"href":"https://github.com/observable-universe/miner/pull/9"},"issue":{"href":"https://api.github.com/repos/observable-universe/miner/issues/9"},"comments":{"href":"https://api.github.com/repos/observable-universe/miner/issues/9/comments"},"review_comments":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/9/comments"},"review_comment":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/observable-universe/miner/pulls/9/commits"},"statuses":{"href":"https://api.github.com/repos/observable-universe/miner/statuses/bce4478891761d0ca41205ce4b4a04898fa1f4b8"}}}}
{"actor":{"display_login":"HeathNaylor"}}