├── .gitignore ├── .meteor ├── .finished-upgraders ├── .gitignore ├── .id ├── packages ├── platforms ├── release └── versions ├── README.md ├── client ├── hubble.css ├── hubble.html ├── issues │ ├── comments.css │ ├── comments.html │ ├── comments.js │ ├── issue.css │ ├── issue.html │ ├── issue.js │ └── models.js ├── labels │ ├── label.css │ ├── label.html │ └── label.js ├── lib │ └── helpers.js ├── main-page │ ├── main.css │ ├── main.html │ └── main.js └── navbar │ ├── navbar.css │ ├── navbar.html │ └── navbar.js ├── packages └── hubble:issue-sync │ ├── .npm │ └── package │ │ ├── .gitignore │ │ ├── README │ │ └── npm-shrinkwrap.json │ ├── README.md │ ├── async.js │ ├── claim.js │ ├── classify.js │ ├── client.js │ ├── config_server.js │ ├── hubble:issue-sync-tests.js │ ├── match.js │ ├── package.js │ ├── sync_server.js │ └── team.js ├── public └── theme.jpg ├── publish.js ├── routes.js └── server └── auth.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 1q95zmslh4a3k1xtb3ch 8 | -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-platform 8 | hubble:issue-sync 9 | twbs:bootstrap 10 | iron:router 11 | accounts-ui 12 | accounts-github 13 | audit-argument-checks 14 | force-ssl 15 | browser-policy 16 | glasser:reactive-fromnow@=0.0.1 17 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.1.0.2 2 | -------------------------------------------------------------------------------- /.meteor/versions: -------------------------------------------------------------------------------- 1 | accounts-base@1.2.0 2 | accounts-github@1.0.4 3 | accounts-oauth@1.1.5 4 | accounts-ui@1.1.5 5 | accounts-ui-unstyled@1.1.7 6 | audit-argument-checks@1.0.3 7 | autoupdate@1.2.1 8 | base64@1.0.3 9 | binary-heap@1.0.3 10 | blaze@2.1.2 11 | blaze-tools@1.0.3 12 | boilerplate-generator@1.0.3 13 | browser-policy@1.0.4 14 | browser-policy-common@1.0.3 15 | browser-policy-content@1.0.4 16 | browser-policy-framing@1.0.4 17 | callback-hook@1.0.3 18 | check@1.0.5 19 | ddp@1.1.0 20 | deps@1.0.7 21 | ejson@1.0.6 22 | fastclick@1.0.3 23 | force-ssl@1.0.4 24 | geojson-utils@1.0.3 25 | github@1.1.3 26 | glasser:reactive-fromnow@0.0.1 27 | html-tools@1.0.4 28 | htmljs@1.0.4 29 | http@1.1.0 30 | hubble:issue-sync@0.0.1 31 | id-map@1.0.3 32 | iron:controller@1.0.7 33 | iron:core@1.0.7 34 | iron:dynamic-template@1.0.7 35 | iron:layout@1.0.7 36 | iron:location@1.0.7 37 | iron:middleware-stack@1.0.7 38 | iron:router@1.0.7 39 | iron:url@1.0.7 40 | jquery@1.11.3_2 41 | json@1.0.3 42 | launch-screen@1.0.2 43 | less@1.0.14 44 | livedata@1.0.13 45 | localstorage@1.0.3 46 | logging@1.0.7 47 | meteor@1.1.6 48 | meteor-platform@1.2.2 49 | minifiers@1.1.5 50 | minimongo@1.0.8 51 | mobile-status-bar@1.0.3 52 | momentjs:moment@2.9.0 53 | mongo@1.1.0 54 | oauth@1.1.4 55 | oauth2@1.1.3 56 | observe-sequence@1.0.6 57 | ordered-dict@1.0.3 58 | random@1.0.3 59 | reactive-dict@1.1.0 60 | reactive-var@1.0.5 61 | reload@1.1.3 62 | retry@1.0.3 63 | routepolicy@1.0.5 64 | service-configuration@1.0.4 65 | session@1.1.0 66 | spacebars@1.0.6 67 | spacebars-compiler@1.0.6 68 | templating@1.1.1 69 | tracker@1.0.7 70 | twbs:bootstrap@3.3.2 71 | ui@1.0.6 72 | underscore@1.0.3 73 | url@1.0.4 74 | webapp@1.2.0 75 | webapp-hashing@1.0.3 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Archival 2 | This repo was archived by the Apollo Security team on 2023-05-26 3 | 4 | Please reach out at security@apollographql.com with questions 5 | 6 | 7 | # githubble 8 | 9 | A tool for triaging GitHub issues. 10 | 11 | ## Dev setup 12 | 13 | You can just run it with Meteor run... but you really want a GitHub access token 14 | so that you can make 5000 API queries/hr instead of 60. And if you want 15 | immediate updates, you have to set up webhooks too. 16 | 17 | ### GitHub access token 18 | 19 | Go to https://github.com/settings/applications and create a "personal access 20 | token" with **NO SCOPES** (ie, *UNCHECK ALL THE SCOPE BOXES*). That will give 21 | you a hex string which is your access token. Put it in the `$GITHUB_TOKEN` 22 | environment variable when running Meteor locally. Note that GitHub will only 23 | give you this token once; it's your job to remember it (or make a new one). 24 | 25 | ### GitHub webhook setup 26 | 27 | First, you'll want to expose your local Meteor app to the internet (exciting!) 28 | 29 | Download and install ngrok from https://ngrok.com/ 30 | 31 | Run it as `ngrok 3000`: this will create a tunnel from a subdomain of ngrok.com 32 | to your localhost:3000, and print the link. (You may want to make sure you have 33 | a dark background for your terminal.) 34 | 35 | Now set up a webhook that points to this URL. Go to https://github.com/meteor/meteor/settings/hooks and click "Add webhook". 36 | 37 | - Set the payload URL to https://whateverngroksaid.ngrok.com/webhook" 38 | - Keep Content type as `application/json` 39 | - Set the secret to a random string (eg `openssl rand -hex 20`), which you should 40 | also set in `$GITHUB_WEBHOOK_SECRET` when you run it (this part is optional 41 | for local dev, but a good idea since otherwise anyone on the internet can 42 | send you webhooks and insert random stuff into your database) 43 | - "Let me select individual events", and choose three events: Issues, Issue 44 | Comment, and Pull request 45 | - "Add webhook" 46 | 47 | ## Production setup 48 | 49 | Uses a Compose (formerly MongoHQ) MongoDB 2.6 installation, so that we get 2.6 50 | and oplog access. Log in to https://app.compose.io/ with the username/password 51 | in LastPass (under mongohq). It's the githubble deployment. I created a database 52 | called githubble, deleted the default user, and created another user in it with 53 | a random password. 54 | 55 | I generated a random string for the webhook secret and a personal access token 56 | (for glasser) for the token. 57 | 58 | The token, secret, and Mongo URLs are in a settings.json in LastPass (we use 59 | settings instead of environment variables). So you don't need to specify 60 | `--settings` on every deploy. 61 | 62 | Note that the oplog URL needs to be on the `local` database (ie the URL path is 63 | `local`) and specify `&authSource=githubble` (ie it gets its authentication from 64 | the main `githubble` database). 65 | 66 | Note also that githubble now runs on Galaxy under the mdg account. `settings.json` can be found in Dropbox, at the date of writing at `/galaxy-prod/keys/Githubble`. 67 | -------------------------------------------------------------------------------- /client/hubble.css: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | .avatar { 3 | height: 50px; 4 | width: 50px; 5 | padding: 2px; 6 | } 7 | 8 | .main { 9 | width: 100vw; 10 | height: 100vh; 11 | background: #004; 12 | } 13 | 14 | .buffer { 15 | height: 3em; 16 | } 17 | 18 | .user { 19 | text-align:center; 20 | } 21 | 22 | body { 23 | background-image: url(theme.jpg); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /client/hubble.html: -------------------------------------------------------------------------------- 1 |
2 |{{body}}16 | trustedCommentHtml: function () { 17 | return this.bodyHtml; 18 | }, 19 | color: function () { 20 | return getCommentColor(this.id); 21 | }, 22 | url: function () { 23 | return this.htmlUrl; 24 | }, 25 | }); 26 | 27 | 28 | Template.comments.events({ 29 | "click .snooze": function () { 30 | Meteor.call('snooze', { 31 | repoOwner: this.repoOwner, 32 | repoName: this.repoName, 33 | number: this.issueDocument.number 34 | }); 35 | Session.set(displayId(this), false); 36 | }, 37 | "click .highly-active": function () { 38 | Meteor.call('setHighlyActive', { 39 | repoOwner: this.repoOwner, 40 | repoName: this.repoName, 41 | number: this.issueDocument.number, 42 | highlyActive: ! this.highlyActive 43 | }); 44 | Session.set(displayId(this), false); 45 | } 46 | }); 47 | 48 | Template.comments.onCreated(function () { 49 | this.subscribe('issue-recent-comments', this.data._id); 50 | }); 51 | 52 | var nextColor = 0; 53 | // Get alternating colors for comments. 54 | var getCommentColor = function (seed) { 55 | var colors = 56 | ["F8F4C3", "F8F9DF"]; 57 | nextColor = (nextColor + 1) % colors.length; 58 | return colors[nextColor]; 59 | }; 60 | -------------------------------------------------------------------------------- /client/issues/issue.css: -------------------------------------------------------------------------------- 1 | /* The entire box */ 2 | .issue { 3 | margin: 2em; 4 | } 5 | 6 | /* Top stripe of the issue */ 7 | .issue-stripe { 8 | height: 1.5em; 9 | margin: 0em; 10 | padding: 0.1em; 11 | border-top-left-radius: 0.5em; 12 | border-top-right-radius: 0.5em; 13 | } 14 | 15 | /* Status displayed in the top stripe */ 16 | .status { 17 | font-family: "Trebuchet MS", Helvetica, sans-serif; 18 | font-size: 95%; 19 | color: #efe; 20 | float: left; 21 | border-top-width: 2px; 22 | border-style: solid; 23 | border-color: transparent; 24 | vertical-align: middle; 25 | } 26 | 27 | .claimed-text { 28 | padding-right: 50px; 29 | color: white; 30 | border-size: 5px; 31 | border-radius: 5px; 32 | } 33 | .claim-button, .unclaim-button { 34 | background-color: green; 35 | border-radius: 2px; 36 | border-size: 2px; 37 | border-color: transparent; 38 | float: right; 39 | cursor: pointer; 40 | } 41 | 42 | .unclaim-button { 43 | background-color: red; 44 | } 45 | 46 | .needs-response { 47 | background-color: white; 48 | border-radius: 2px; 49 | border-size: 2px; 50 | border-color: transparent; 51 | float: right; 52 | cursor: pointer; 53 | } 54 | .needs-response:hover { 55 | background-color: blue; 56 | } 57 | 58 | /* Non-project labels in the top stripe */ 59 | .issue-labels { 60 | vertical-align: middle; 61 | margin-right: 10px; 62 | float: right; 63 | } 64 | 65 | /* Main issue body */ 66 | .issue-body { 67 | cursor: pointer; 68 | background-color: #fff; 69 | border-top: 4px; 70 | border-left: 4px; 71 | border-right: 0px; 72 | border-bottom: 0px; 73 | border-style: solid; 74 | border-color: white; 75 | padding: 0px; 76 | margin: 0px; 77 | position: relative; 78 | border-bottom-left-radius: 0.5em; 79 | border-bottom-right-radius: 0.5em; 80 | box-shadow: 1px 5px 5px #333; 81 | } 82 | 83 | /* Title in the issue body */ 84 | .issue-title { 85 | padding: 0.5em; 86 | font-family: "Trebuchet MS", Helvetica, sans-serif; 87 | } 88 | 89 | .issue-label-row { 90 | vertical-align: middle; 91 | margin-right: 10px; 92 | float: left; 93 | } 94 | 95 | /* avatar */ 96 | .avatar { 97 | height: 50px; 98 | width: 50px; 99 | padding: 2px; 100 | } 101 | .avatar-wrap { 102 | margin: 5px; 103 | float: left; 104 | width: 75px; 105 | } 106 | 107 | .user-login { 108 | margin-bottom: 0; 109 | } 110 | 111 | /* comments */ 112 | .issue-comments { 113 | cursor: pointer; 114 | float: right; 115 | 116 | font-family: "Trebuchet MS", Helvetica, sans-serif; 117 | background: linear-gradient(to right, #eee, #eef); 118 | color: #001; 119 | width: 10em; 120 | font-weight: bold; 121 | text-align: center; 122 | 123 | margin: 0em; 124 | padding: 0.5em; 125 | 126 | box-shadow: 1px 5px 5px #222; 127 | border-bottom-right-radius: 0.5em; 128 | 129 | height: 2.5em; 130 | 131 | position: absolute; 132 | bottom: 0; 133 | right: 0; 134 | } 135 | 136 | 137 | .issue-comments.true{ 138 | background: linear-gradient(to right, #345, #446); 139 | color: #eef; 140 | } 141 | 142 | .issue-comments.true:hover{ 143 | background: linear-gradient(to right, #eee, #eef); 144 | } 145 | 146 | .issue-comments:hover { 147 | background: linear-gradient(to right, #345, #446); 148 | color: #eef; 149 | } 150 | 151 | .issue-number { 152 | width: 6em; 153 | font-weight: bold; 154 | } 155 | 156 | 157 | .top-level-snooze { 158 | cursor: pointer; 159 | float: right; 160 | 161 | font-family: "Trebuchet MS", Helvetica, sans-serif; 162 | background: linear-gradient(to right, #eee, #eef); 163 | color: #001; 164 | width: 10em; 165 | font-weight: bold; 166 | text-align: center; 167 | 168 | margin: 0em; 169 | padding: 0.5em; 170 | 171 | box-shadow: 1px 5px 5px #222; 172 | border-bottom-right-radius: 0.5em; 173 | 174 | height: 2.5em; 175 | 176 | position: absolute; 177 | bottom: 0; 178 | right: 0; 179 | } 180 | .top-level-snooze:hover { 181 | background: linear-gradient(to right, #345, #446); 182 | color: #eef; 183 | } 184 | -------------------------------------------------------------------------------- /client/issues/issue.html: -------------------------------------------------------------------------------- 1 | 2 |
{{ user.login }}
77 | 78 |