diff --git a/README.md b/README.md
index 2e0a3c2..0bd5b64 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ Note: heroku domain should match subdomain of topcoder-dev or topcoder depending
 
 ## Verification
 
-- run `npm serve` to start the app
+- run `npm run serve` to start the app
 - go to topcoderx.topcoder-dev.com and it will redirect to Topcoder login page, after successful login it will redirect back to Topcoder x app.
 - go to settings by clicking username at top right corner
 - setup both git provider to authorize topcoder-x to manage your repo on behalf of you
diff --git a/package-lock.json b/package-lock.json
index 986a2de..1a1b260 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -207,6 +207,11 @@
                 }
             }
         },
+        "@sindresorhus/is": {
+            "version": "0.7.0",
+            "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+            "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow=="
+        },
         "@types/node": {
             "version": "6.0.111",
             "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.111.tgz",
@@ -666,8 +671,7 @@
         "assertion-error": {
             "version": "1.0.2",
             "resolved": "http://registry.npm.taobao.org/assertion-error/download/assertion-error-1.0.2.tgz",
-            "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
-            "dev": true
+            "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw="
         },
         "assign-symbols": {
             "version": "1.0.0",
@@ -2013,8 +2017,7 @@
         "browser-stdout": {
             "version": "1.3.0",
             "resolved": "http://registry.npm.taobao.org/browser-stdout/download/browser-stdout-1.3.0.tgz",
-            "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
-            "dev": true
+            "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8="
         },
         "browser-sync": {
             "version": "2.18.13",
@@ -2912,6 +2915,27 @@
                 "unset-value": "^1.0.0"
             }
         },
+        "cacheable-request": {
+            "version": "2.1.4",
+            "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+            "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
+            "requires": {
+                "clone-response": "1.0.2",
+                "get-stream": "3.0.0",
+                "http-cache-semantics": "3.8.1",
+                "keyv": "3.0.0",
+                "lowercase-keys": "1.0.0",
+                "normalize-url": "2.0.1",
+                "responselike": "1.0.2"
+            },
+            "dependencies": {
+                "lowercase-keys": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+                    "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY="
+                }
+            }
+        },
         "caller-path": {
             "version": "0.1.0",
             "resolved": "http://registry.npm.taobao.org/caller-path/download/caller-path-0.1.0.tgz",
@@ -2980,7 +3004,6 @@
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
             "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
-            "dev": true,
             "requires": {
                 "assertion-error": "^1.0.1",
                 "check-error": "^1.0.1",
@@ -3058,8 +3081,7 @@
         "check-error": {
             "version": "1.0.2",
             "resolved": "http://registry.npm.taobao.org/check-error/download/check-error-1.0.2.tgz",
-            "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
-            "dev": true
+            "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
         },
         "chokidar": {
             "version": "1.7.0",
@@ -3207,6 +3229,14 @@
             "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
             "dev": true
         },
+        "clone-response": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+            "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+            "requires": {
+                "mimic-response": "^1.0.0"
+            }
+        },
         "clone-stats": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
@@ -3385,8 +3415,7 @@
         "commander": {
             "version": "2.11.0",
             "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
-            "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
-            "dev": true
+            "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
         },
         "commondir": {
             "version": "0.0.1",
@@ -3860,14 +3889,20 @@
         "decode-uri-component": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
-            "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
-            "dev": true
+            "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+        },
+        "decompress-response": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+            "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+            "requires": {
+                "mimic-response": "^1.0.0"
+            }
         },
         "deep-eql": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
             "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
-            "dev": true,
             "requires": {
                 "type-detect": "^4.0.0"
             }
@@ -4253,6 +4288,11 @@
                 }
             }
         },
+        "duplexer3": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+            "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+        },
         "duplexify": {
             "version": "3.6.0",
             "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
@@ -6034,6 +6074,20 @@
             "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
             "dev": true
         },
+        "from2": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+            "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+            "requires": {
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0"
+            }
+        },
+        "fs-copy-file-sync": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz",
+            "integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ=="
+        },
         "fs-exists-sync": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
@@ -6043,8 +6097,7 @@
         "fs.realpath": {
             "version": "1.0.0",
             "resolved": "http://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz",
-            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-            "dev": true
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
         },
         "fsevents": {
             "version": "1.2.4",
@@ -6617,8 +6670,7 @@
         "get-func-name": {
             "version": "2.0.0",
             "resolved": "http://registry.npm.taobao.org/get-func-name/download/get-func-name-2.0.0.tgz",
-            "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
-            "dev": true
+            "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
         },
         "get-parameter-names": {
             "version": "0.3.0",
@@ -6631,6 +6683,11 @@
             "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
             "dev": true
         },
+        "get-stream": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+            "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+        },
         "get-value": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -6766,7 +6823,6 @@
             "version": "7.1.2",
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
             "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-            "dev": true,
             "requires": {
                 "fs.realpath": "^1.0.0",
                 "inflight": "^1.0.4",
@@ -7063,6 +7119,37 @@
                 "sparkles": "^1.0.0"
             }
         },
+        "got": {
+            "version": "8.3.1",
+            "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz",
+            "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==",
+            "requires": {
+                "@sindresorhus/is": "^0.7.0",
+                "cacheable-request": "^2.1.1",
+                "decompress-response": "^3.3.0",
+                "duplexer3": "^0.1.4",
+                "get-stream": "^3.0.0",
+                "into-stream": "^3.1.0",
+                "is-retry-allowed": "^1.1.0",
+                "isurl": "^1.0.0-alpha5",
+                "lowercase-keys": "^1.0.0",
+                "mimic-response": "^1.0.0",
+                "p-cancelable": "^0.4.0",
+                "p-timeout": "^2.0.1",
+                "pify": "^3.0.0",
+                "safe-buffer": "^5.1.1",
+                "timed-out": "^4.0.1",
+                "url-parse-lax": "^3.0.0",
+                "url-to-options": "^1.0.1"
+            },
+            "dependencies": {
+                "pify": {
+                    "version": "3.0.0",
+                    "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+                    "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+                }
+            }
+        },
         "graceful-fs": {
             "version": "4.1.11",
             "resolved": "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.11.tgz",
@@ -9511,6 +9598,19 @@
                 "escape-string-regexp": "^1.0.3"
             }
         },
+        "has-symbol-support-x": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+            "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
+        },
+        "has-to-string-tag-x": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+            "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+            "requires": {
+                "has-symbol-support-x": "^1.4.1"
+            }
+        },
         "has-value": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -9593,6 +9693,11 @@
                 "sntp": "1.x.x"
             }
         },
+        "he": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+            "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
+        },
         "hmac-drbg": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -9657,6 +9762,11 @@
                 }
             }
         },
+        "http-cache-semantics": {
+            "version": "3.8.1",
+            "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+            "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w=="
+        },
         "http-errors": {
             "version": "1.6.2",
             "resolved": "http://registry.npm.taobao.org/http-errors/download/http-errors-1.6.2.tgz",
@@ -9777,7 +9887,6 @@
             "version": "1.0.6",
             "resolved": "http://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz",
             "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-            "dev": true,
             "requires": {
                 "once": "^1.3.0",
                 "wrappy": "1"
@@ -10031,6 +10140,15 @@
             "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=",
             "dev": true
         },
+        "into-stream": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+            "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+            "requires": {
+                "from2": "^2.1.1",
+                "p-is-promise": "^1.1.0"
+            }
+        },
         "invariant": {
             "version": "2.2.2",
             "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
@@ -10254,6 +10372,11 @@
                 "lodash.isfinite": "^3.3.2"
             }
         },
+        "is-object": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+            "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
+        },
         "is-odd": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
@@ -10295,6 +10418,11 @@
                 "path-is-inside": "^1.0.1"
             }
         },
+        "is-plain-obj": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+            "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+        },
         "is-plain-object": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -10363,6 +10491,11 @@
                 "tryit": "^1.0.1"
             }
         },
+        "is-retry-allowed": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+            "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
+        },
         "is-stream": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -10443,6 +10576,15 @@
                 "textextensions": "~1.0.0"
             }
         },
+        "isurl": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+            "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+            "requires": {
+                "has-to-string-tag-x": "^1.2.0",
+                "is-object": "^1.0.1"
+            }
+        },
         "items": {
             "version": "2.1.1",
             "resolved": "http://registry.npm.taobao.org/items/download/items-2.1.1.tgz",
@@ -10673,6 +10815,11 @@
                 }
             }
         },
+        "json-buffer": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+            "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
+        },
         "json-fallback": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/json-fallback/-/json-fallback-0.0.1.tgz",
@@ -10892,6 +11039,14 @@
             "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz",
             "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg="
         },
+        "keyv": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+            "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+            "requires": {
+                "json-buffer": "3.0.0"
+            }
+        },
         "kind-of": {
             "version": "3.2.2",
             "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@@ -11807,6 +11962,11 @@
             "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
             "dev": true
         },
+        "lowercase-keys": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+            "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+        },
         "lru-cache": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
@@ -12112,6 +12272,11 @@
             "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
             "dev": true
         },
+        "mimic-response": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
+            "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
+        },
         "min-document": {
             "version": "2.19.0",
             "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
@@ -12217,7 +12382,6 @@
             "version": "0.5.1",
             "resolved": "http://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz",
             "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-            "dev": true,
             "requires": {
                 "minimist": "0.0.8"
             },
@@ -12225,8 +12389,7 @@
                 "minimist": {
                     "version": "0.0.8",
                     "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-                    "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-                    "dev": true
+                    "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
                 }
             }
         },
@@ -12732,6 +12895,16 @@
                 "remove-trailing-separator": "^1.0.1"
             }
         },
+        "normalize-url": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+            "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+            "requires": {
+                "prepend-http": "^2.0.0",
+                "query-string": "^5.0.1",
+                "sort-keys": "^2.0.0"
+            }
+        },
         "number-is-nan": {
             "version": "1.0.1",
             "resolved": "http://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz",
@@ -12897,7 +13070,6 @@
             "version": "1.4.0",
             "resolved": "http://registry.npm.taobao.org/once/download/once-1.4.0.tgz",
             "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-            "dev": true,
             "requires": {
                 "wrappy": "1"
             }
@@ -13021,6 +13193,21 @@
                 "os-tmpdir": "^1.0.0"
             }
         },
+        "p-cancelable": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+            "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ=="
+        },
+        "p-finally": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+            "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+        },
+        "p-is-promise": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+            "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4="
+        },
         "p-limit": {
             "version": "1.1.0",
             "resolved": "http://registry.npm.taobao.org/p-limit/download/p-limit-1.1.0.tgz",
@@ -13036,6 +13223,14 @@
                 "p-limit": "^1.1.0"
             }
         },
+        "p-timeout": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+            "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+            "requires": {
+                "p-finally": "^1.0.0"
+            }
+        },
         "pace-js": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/pace-js/-/pace-js-1.0.2.tgz",
@@ -13083,6 +13278,68 @@
                 "pbkdf2": "^3.0.3"
             }
         },
+        "parse-domain": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-2.1.2.tgz",
+            "integrity": "sha512-I1HuHXYL8hZp9MYf0jHZE2nW0qhJnqBAxKOR9sGCbiBoD3znYrp4nh3SH9dkt2+f6gEenEj6sh537FTNe+QBqg==",
+            "requires": {
+                "chai": "^4.1.2",
+                "fs-copy-file-sync": "^1.1.1",
+                "got": "^8.0.1",
+                "mkdirp": "^0.5.1",
+                "mocha": "^4.0.1"
+            },
+            "dependencies": {
+                "debug": {
+                    "version": "3.1.0",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+                    "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+                    "requires": {
+                        "ms": "2.0.0"
+                    }
+                },
+                "diff": {
+                    "version": "3.3.1",
+                    "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
+                    "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww=="
+                },
+                "growl": {
+                    "version": "1.10.3",
+                    "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
+                    "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q=="
+                },
+                "has-flag": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+                    "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+                },
+                "mocha": {
+                    "version": "4.1.0",
+                    "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
+                    "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
+                    "requires": {
+                        "browser-stdout": "1.3.0",
+                        "commander": "2.11.0",
+                        "debug": "3.1.0",
+                        "diff": "3.3.1",
+                        "escape-string-regexp": "1.0.5",
+                        "glob": "7.1.2",
+                        "growl": "1.10.3",
+                        "he": "1.1.1",
+                        "mkdirp": "0.5.1",
+                        "supports-color": "4.4.0"
+                    }
+                },
+                "supports-color": {
+                    "version": "4.4.0",
+                    "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+                    "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+                    "requires": {
+                        "has-flag": "^2.0.0"
+                    }
+                }
+            }
+        },
         "parse-filepath": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -13258,8 +13515,7 @@
         "path-is-absolute": {
             "version": "1.0.1",
             "resolved": "http://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
-            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-            "dev": true
+            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
         "path-is-inside": {
             "version": "1.0.2",
@@ -13313,8 +13569,7 @@
         "pathval": {
             "version": "1.1.0",
             "resolved": "http://registry.npm.taobao.org/pathval/download/pathval-1.1.0.tgz",
-            "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
-            "dev": true
+            "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA="
         },
         "pause-stream": {
             "version": "0.0.11",
@@ -13488,6 +13743,11 @@
             "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
             "dev": true
         },
+        "prepend-http": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+            "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
+        },
         "preserve": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
@@ -13702,6 +13962,16 @@
             "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
             "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
         },
+        "query-string": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+            "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+            "requires": {
+                "decode-uri-component": "^0.2.0",
+                "object-assign": "^4.1.0",
+                "strict-uri-encode": "^1.0.0"
+            }
+        },
         "querystring": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@@ -14372,6 +14642,14 @@
                 "minimatch": "^3.0.2"
             }
         },
+        "responselike": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+            "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+            "requires": {
+                "lowercase-keys": "^1.0.0"
+            }
+        },
         "restore-cursor": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
@@ -14989,6 +15267,14 @@
                 }
             }
         },
+        "sort-keys": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+            "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+            "requires": {
+                "is-plain-obj": "^1.0.0"
+            }
+        },
         "source-map": {
             "version": "0.5.7",
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -15390,6 +15676,11 @@
                 "limiter": "^1.0.5"
             }
         },
+        "strict-uri-encode": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+            "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+        },
         "string-length": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
@@ -15743,6 +16034,11 @@
                 "os-homedir": "^1.0.0"
             }
         },
+        "timed-out": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+            "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+        },
         "timers-ext": {
             "version": "0.1.5",
             "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.5.tgz",
@@ -15966,8 +16262,7 @@
         "type-detect": {
             "version": "4.0.3",
             "resolved": "http://registry.npm.taobao.org/type-detect/download/type-detect-4.0.3.tgz",
-            "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=",
-            "dev": true
+            "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo="
         },
         "type-is": {
             "version": "1.6.15",
@@ -16165,6 +16460,19 @@
             "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
             "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo="
         },
+        "url-parse-lax": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+            "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+            "requires": {
+                "prepend-http": "^2.0.0"
+            }
+        },
+        "url-to-options": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+            "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
+        },
         "use": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
@@ -16760,8 +17068,7 @@
         "wrappy": {
             "version": "1.0.2",
             "resolved": "http://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz",
-            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-            "dev": true
+            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
         },
         "write": {
             "version": "0.2.1",
diff --git a/package.json b/package.json
index c5de358..22b53e6 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
         "mongoose": "^4.11.9",
         "octonode": "^0.9.2",
         "pace-js": "~1.0.2",
+        "parse-domain": "^2.1.2",
         "shortid": "^2.2.8",
         "superagent": "^3.6.0",
         "superagent-promise": "^1.1.0",
diff --git a/src/common/helper.js b/src/common/helper.js
index f801875..6018a12 100644
--- a/src/common/helper.js
+++ b/src/common/helper.js
@@ -15,13 +15,16 @@ const getParams = require('get-parameter-names');
 const bluebird = require('bluebird');
 const uuid = require('uuid/v4');
 const bcrypt = require('bcryptjs');
+const parseDomain = require('parse-domain');
 const config = require('../config');
 const logger = require('./logger');
 const errors = require('./errors');
 const constants = require('./constants');
 const NotFoundError = require('./errors').NotFoundError;
+const ValidationError = require('./errors').ValidationError;
 
 bluebird.promisifyAll(bcrypt);
+bluebird.promisifyAll(parseDomain);
 
 /**
  * Convert array with arguments to object
@@ -82,7 +85,7 @@ function _decorateWithValidators(service) {
     const params = getParams(method);
     service[name] = async function serviceMethodWithValidation(...args) {
       const value = _combineObject(params, args);
-      const normalized = Joi.attempt(value, method.schema, {abortEarly: false});
+      const normalized = Joi.attempt(value, method.schema, { abortEarly: false });
       // Joi will normalize values
       // for example string number '1' to 1
       // if schema type is number
@@ -188,6 +191,42 @@ async function ensureExists(Model, criteria) {
   return result;
 }
 
+/**
+ * get the provider name from git repo url
+ * @param {String} repoUrl the project repo URL
+ * @returns {String} the provider
+ */
+async function getProviderType(repoUrl) {
+  const parsedDomain = await parseDomain(repoUrl);
+  if (!parsedDomain || !parsedDomain.domain || (parsedDomain.domain !== 'github' && parsedDomain.domain !== 'gitlab')) {
+    throw new ValidationError('Invalid git repo url');
+  }
+  return parsedDomain.domain;
+}
+
+/**
+ * gets the git username of copilot for a project
+ * @param {Object} models the db models
+ * @param {Object} project the db project detail
+ * @param {String} provider the git provider
+ * @returns {Object} the owner/copilot for the project
+ */
+async function getProjectOwner(models, project, provider) {
+  const userMapping = await models.UserMapping.findOne({
+    topcoderUsername: project.username,
+  });
+
+  if (!userMapping || (provider === 'github' && !userMapping.githubUserId) || (provider === 'gitlab' && !userMapping.gitlabUserId)) {
+    throw new Error(`Couldn't find owner username for '${provider}' for this repository.`);
+  }
+
+  const copilot = await models.User.findOne({
+    username: provider === 'github' ? userMapping.githubUsername : userMapping.gitlabUsername,
+    type: provider,
+  });
+  return copilot;
+}
+
 
 /**
  * Generate an unique identifier
@@ -206,4 +245,6 @@ module.exports = {
   convertGitLabError,
   ensureExists,
   generateIdentifier,
+  getProviderType,
+  getProjectOwner,
 };
diff --git a/src/controllers/ProjectController.js b/src/controllers/ProjectController.js
index 6f92ad3..acf2d6d 100644
--- a/src/controllers/ProjectController.js
+++ b/src/controllers/ProjectController.js
@@ -18,7 +18,7 @@ const ProjectService = require('../services/ProjectService');
  * @returns {Object} the result
  */
 async function create(req) {
-  return await ProjectService.create(req.body);
+  return await ProjectService.create(req.body, req.currentUser.handle);
 }
 
 /**
@@ -28,7 +28,7 @@ async function create(req) {
  * @returns {Object} the result
  */
 async function update(req) {
-  return await ProjectService.update(req.body);
+  return await ProjectService.update(req.body, req.currentUser.handle);
 }
 
 /**
@@ -37,7 +37,7 @@ async function update(req) {
  * @returns {Array} the result
  */
 async function getAll(req) {
-  return await ProjectService.getAll(req.query.status);
+  return await ProjectService.getAll(req.query.status, req.currentUser.handle);
 }
 
 /**
@@ -47,7 +47,7 @@ async function getAll(req) {
  * @returns {Object} the result
  */
 async function createLabel(req) {
-  return await ProjectService.createLabel(req.body);
+  return await ProjectService.createLabel(req.body, req.currentUser.handle);
 }
 
 /**
@@ -57,7 +57,7 @@ async function createLabel(req) {
  * @returns {Object} the result
  */
 async function createHook(req) {
-  return await ProjectService.createHook(req.body);
+  return await ProjectService.createHook(req.body, req.currentUser.handle);
 }
 
 module.exports = {
diff --git a/src/front/src/.eslintrc b/src/front/src/.eslintrc
index b5b619a..5782540 100644
--- a/src/front/src/.eslintrc
+++ b/src/front/src/.eslintrc
@@ -5,7 +5,10 @@
   "rules": {
     "angular/no-service-method": 0,
     "angular/window-service": 0,
-    "angular/di": [2, "array"],
+    "angular/di": [
+      2,
+      "array"
+    ],
     "angular/angularelement": 0,
     "angular/timeout-service": 0,
     "max-params": 0,
@@ -14,19 +17,21 @@
     "valid-jsdoc": 0,
     "require-jsdoc": 0,
     "no-magic-numbers": 0,
-    "no-invalid-this" : 0,
-    "no-nested-ternary" : 0,
-    "no-void" : 0,
-    "consistent-return" : 0,
-    "lodash/prefer-includes" : 0,
-    "one-var" : 0,
-    "no-restricted-syntax" : 0,
-    "func-style" : 0,
-    "vars-on-top" : 0,
-    "func-names" : 0,
-    "prefer-rest-params" : 0,
-    "no-var":0,
-    "no-inner-declarations":0
+    "no-invalid-this": 0,
+    "no-nested-ternary": 0,
+    "no-void": 0,
+    "consistent-return": 0,
+    "lodash/prefer-includes": 0,
+    "one-var": 0,
+    "no-restricted-syntax": 0,
+    "func-style": 0,
+    "vars-on-top": 0,
+    "func-names": 0,
+    "prefer-rest-params": 0,
+    "no-var": 0,
+    "no-inner-declarations": 0,
+    "prefer-arrow-callback": 0,
+    "prefer-template":0,
   },
   "env": {
     "browser": true,
@@ -34,4 +39,4 @@
     "es6": true,
     "jquery": true
   }
-}
+}
\ No newline at end of file
diff --git a/src/front/src/app/projects/projects.html b/src/front/src/app/projects/projects.html
index 53ce9ef..2b7f14d 100644
--- a/src/front/src/app/projects/projects.html
+++ b/src/front/src/app/projects/projects.html
@@ -42,7 +42,7 @@ <h4>You don't have active projects right now. Please
                                                 </tr>
                                             </thead>
                                             <tbody>
-                                                <tr ng-repeat="project in projects" class="animate-repeat" ng-class-even="'footable-even'" ng-class-odd="'footable-odd'">
+                                                <tr ng-repeat="project in projects" ng-class-even="'footable-even'" ng-class-odd="'footable-odd'">
                                                     <td class="col-lg-2">{{project.title}}</td>
                                                     <td class="col-lg-2">
                                                         <a href="{{directUrlBase}}{{project.tcDirectId}}" target="_blank">{{project.tcDirectId}}</a>
diff --git a/src/front/src/app/upsertproject/upsertproject.controller.js b/src/front/src/app/upsertproject/upsertproject.controller.js
index fa1139b..7b18fad 100644
--- a/src/front/src/app/upsertproject/upsertproject.controller.js
+++ b/src/front/src/app/upsertproject/upsertproject.controller.js
@@ -8,20 +8,20 @@
 angular.module('topcoderX').controller('ProjectController', ['currentUser', '$scope', '$timeout', 'ProjectService',
   '$rootScope', '$state', 'Alert', function (currentUser, $scope, $timeout, ProjectService, $rootScope, $state, Alert) {
 
-    //Maintain the navigation state.
+    // Maintain the navigation state.
     $timeout(function () {
       angular.element('#projectsManagement').addClass('active');
     }, 0);
 
-    //below logic is trying to identify whether we are editing a project
+    // below logic is trying to identify whether we are editing a project
     $scope.editing = true;
     $scope.project = {
-      'title': '',
-      'tcDirectId': '',
-      'repoUrl': '',
-      'rocketChatWebhook': null,
-      'rocketChatChannelName': null,
-      'archived': false
+      title: '',
+      tcDirectId: '',
+      repoUrl: '',
+      rocketChatWebhook: null,
+      rocketChatChannelName: null,
+      archived: false,
     };
     if ($rootScope.project) {
       $scope.title = 'Edit a Project';
@@ -33,97 +33,40 @@ angular.module('topcoderX').controller('ProjectController', ['currentUser', '$sc
       $scope.editing = false;
     }
 
-    //represents the repo owner
-    $scope.repoOwner = '';
-
-    //represents the repo name
-    $scope.repoName = '';
-
-    //represents the repo is located at github or gitlab
-    $scope.repoType = '';
-
-    //function to get the repo's owner and the repo's name based on repoUrl
-    const getRepoDetail = function (repoUrl, callback, errorCallBack) {
-      $scope.$broadcast('alert.ClearAll', {});
-      if (repoUrl.endsWith('/')) {
-        repoUrl = repoUrl.slice(0, -1);
-      }
-      const results = repoUrl.split('/');
-      $scope.repoName = results[results.length - 1];
-      $scope.repoOwner = results[results.length - 2];
-      $scope.repoType = results[results.length - 3].split('.')[0];
-      ProjectService.getUserToken($scope.repoOwner, $scope.repoType).then(function (response) {
-        if (angular.isDefined(response.data.token)) {
-          $scope.token = response.data.token;
-          return callback();
-        } else {
-          const erroMessage = 'Token not found for the user ' + $scope.repoOwner + ' of type ' + $scope.repoType + ' please complete profile setting';
-          Alert.error(erroMessage, $scope);
-        }
-      }, function (error) {
-        errorCallBack(error);
-      });
-    };
-
-    //function to add labels to the current project.
+    // function to add labels to the current project.
     $scope.addLabels = function () {
-      getRepoDetail($scope.project.repoUrl, function () {
-        // for (var i = 0; i < $rootScope.config.LABELS.length; i++) {
-        var objc = {
-          'repoOwner': $scope.repoOwner,
-          'repoName': $scope.repoName,
-          'repoToken': $scope.token,
-         
-          'repoType': $scope.repoType
-        };
-        ProjectService.createLabel(objc).then(function () {
-          Alert.info('Label Added Successfully', $scope);
-        }).catch(function (error) {
-          Alert.error(error.data.message, $scope);
-        });
-        // }
-      }, function (error) {
+      ProjectService.createLabel({ projectId: $scope.project.id }).then(function () {
+        Alert.info('Label Added Successfully', $scope);
+      }).catch(function (error) {
         Alert.error(error.data.message, $scope);
       });
     };
 
-    //function to add hooks to the current project.
+    // function to add hooks to the current project.
     $scope.addHooks = function () {
-      getRepoDetail($scope.project.repoUrl, function () {
-        var objc = {
-          'repoOwner': $scope.repoOwner,
-          'repoName': $scope.repoName,
-          'repoToken': $scope.token,
-          'repoType': $scope.repoType,
-          'projectId': $scope.project.id
-        };
-        ProjectService.createHooks(objc).then(function () {
-          Alert.info('Webhook Added Successfully', $scope);
-        }).catch(function (error) {
-          Alert.error(error.data.message, $scope);
-        });
-      }, function (error) {
+      ProjectService.createHooks({ projectId: $scope.project.id }).then(function () {
+        Alert.info('Webhook Added Successfully', $scope);
+      }).catch(function (error) {
         Alert.error(error.data.message, $scope);
       });
     };
 
-    //save the project info to database, and go back to project list view.
+    // save the project info to database, and go back to project list view.
     $scope.save = function () {
-      $scope.project.username = $rootScope.currentUser.handle;
       if ($scope.editing) {
         ProjectService.update($scope.project).then(function () {
           Alert.info('Project Updated Successfully', $scope);
           $state.go('app.projects');
-        }).catch((function (error) {
+        }).catch(function (error) {
           Alert.error(error.data.message, $scope);
-        }))
+        });
       } else {
         ProjectService.create($scope.project).then(function () {
           Alert.info('Project Created Successfully', $scope);
           $state.go('app.projects');
         }).catch(function (error) {
           Alert.error(error.data.message, $scope);
-        })
+        });
       }
-    }
+    };
   }]);
diff --git a/src/services/ProjectService.js b/src/services/ProjectService.js
index a88ead0..a400ea0 100644
--- a/src/services/ProjectService.js
+++ b/src/services/ProjectService.js
@@ -15,9 +15,10 @@ const _ = require('lodash');
 const guid = require('guid');
 const kafka = require('../utils/kafka');
 const helper = require('../common/helper');
-const Project = require('../models').Project;
+const models = require('../models');
 const config = require('../config');
 
+const Project = models.Project;
 const projectSchema = {
   project: {
     id: Joi.string().required(),
@@ -29,7 +30,8 @@ const projectSchema = {
     archived: Joi.boolean().required(),
     username: Joi.string().required(),
     secretWebhookKey: Joi.string().required(),
-  }
+  },
+  currentUserTopcoderHandle: Joi.string().required(),
 };
 
 const createProjectSchema = {
@@ -40,16 +42,18 @@ const createProjectSchema = {
     rocketChatWebhook: Joi.string().allow(null),
     rocketChatChannelName: Joi.string().allow(null),
     archived: Joi.boolean().required(),
-    username: Joi.string().required(),
-  }
+  },
+  currentUserTopcoderHandle: Joi.string().required(),
 };
 
 /**
  * creates project
  * @param {Object} project the project detail
+ * @param {String} currentUserTopcoderHandle the topcoder handle of current user
  * @returns {Object} created project
  */
-async function create(project) {
+async function create(project, currentUserTopcoderHandle) {
+  await helper.getProviderType(project.repoUrl);
   /**
      * Uncomment below code to enable the function of raising event when 'project was created'
      *
@@ -58,7 +62,7 @@ async function create(project) {
      * }
      * await kafka.send(JSON.stringify(JSON.stringify(projectCreateEvent)));
      */
-  project.username = project.username.toLowerCase();
+  project.username = currentUserTopcoderHandle;
   project.secretWebhookKey = guid.raw();
   const dbProject = new Project(project);
   return await dbProject.save();
@@ -69,9 +73,11 @@ create.schema = createProjectSchema;
 /**
  * updates project
  * @param {Object} project the project detail
+ * @param {String} currentUserTopcoderHandle the topcoder handle of current user
  * @returns {Object} updated project
  */
-async function update(project) {
+async function update(project, currentUserTopcoderHandle) {
+  await helper.getProviderType(project.repoUrl);
   const dbProject = await helper.ensureExists(Project, project.id);
   if (dbProject.archived === 'false' && project.archived === true) {
     // project archived detected.
@@ -90,7 +96,7 @@ async function update(project) {
      * }
      * await kafka.send(JSON.stringify(JSON.stringify(projectUpdateEvent)));
      */
-  project.username = project.username.toLowerCase();
+  project.username = currentUserTopcoderHandle;
   Object.entries(project).map((item) => {
     dbProject[item[0]] = item[1];
     return item;
@@ -103,29 +109,44 @@ update.schema = projectSchema;
 /**
  * gets all projects
  * @param {String} status the status of project
+ * @param {String} currentUserTopcoderHandle the topcoder handle of current user
  * @returns {Array} all projects
  */
-async function getAll(status) {
+async function getAll(status, currentUserTopcoderHandle) {
   if (status === 'archived') {
-    return await Project.find({ archived: true });
+    return await Project.find({ archived: true, username: currentUserTopcoderHandle });
   }
-  return await Project.find({ archived: false });
+  return await Project.find({ archived: false, username: currentUserTopcoderHandle });
 }
 
 getAll.schema = Joi.object().keys({
   status: Joi.string().required().allow('active', 'archived').default('active'),
+  currentUserTopcoderHandle: Joi.string().required(),
 });
 
 /**
  * creates label
  * @param {Object} body the request body
+ * @param {String} currentUserTopcoderHandle the topcoder handle of current user
  * @returns {Object} result
  */
-async function createLabel(body) {
-  if (body.repoType === 'github') {
+async function createLabel(body, currentUserTopcoderHandle) {
+  const dbProject = await helper.ensureExists(Project, body.projectId);
+  if (dbProject.username !== currentUserTopcoderHandle) {
+    dbProject.username = currentUserTopcoderHandle;
+    await dbProject.save();
+  }
+  const provider = await helper.getProviderType(dbProject.repoUrl);
+  const copilot = await helper.getProjectOwner(models, dbProject, provider);
+  const results = dbProject.repoUrl.split('/');
+  let index = 1;
+  const repoName = results[results.length - index];
+  index += 1;
+  const repoOwner = results[results.length - index];
+  if (provider === 'github') {
     try {
-      const client = gitHubApi.client(body.repoToken);
-      const ghrepo = client.repo(`${body.repoOwner}/${body.repoName}`);
+      const client = gitHubApi.client(copilot.accessToken);
+      const ghrepo = client.repo(`${repoOwner}/${repoName}`);
       await Promise.all(config.LABELS.map(async (label) => {
         await new Promise((resolve, reject) => {
           ghrepo.label({
@@ -149,10 +170,10 @@ async function createLabel(body) {
     try {
       const client = new Gitlab({
         url: config.GITLAB_API_BASE_URL,
-        oauthToken: body.repoToken,
+        oauthToken: copilot.accessToken,
       });
       await Promise.all(config.LABELS.map(async (label) => {
-        await client.Labels.create(`${body.repoOwner}/${body.repoName}`, {
+        await client.Labels.create(`${repoOwner}/${repoName}`, {
           name: label.name,
           color: `#${label.color}`,
         });
@@ -168,24 +189,34 @@ async function createLabel(body) {
 
 createLabel.schema = Joi.object().keys({
   body: Joi.object().keys({
-    repoType: Joi.string().required(),
-    repoToken: Joi.string().required(),
-    repoOwner: Joi.string().required(),
-    repoName: Joi.string().required(),
+    projectId: Joi.string().required(),
   }),
+  currentUserTopcoderHandle: Joi.string().required(),
 });
 
 /**
  * creates hook
  * @param {Object} body the request body
+ * @param {String} currentUserTopcoderHandle the topcoder handle of current user
  * @returns {Object} result
  */
-async function createHook(body) {
-  const projectDetail = await helper.ensureExists(Project, body.projectId);
-  if (body.repoType === 'github') {
+async function createHook(body, currentUserTopcoderHandle) {
+  const dbProject = await helper.ensureExists(Project, body.projectId);
+  if (dbProject.username !== currentUserTopcoderHandle) {
+    dbProject.username = currentUserTopcoderHandle;
+    await dbProject.save();
+  }
+  const provider = await helper.getProviderType(dbProject.repoUrl);
+  const copilot = await helper.getProjectOwner(models, dbProject, provider);
+  const results = dbProject.repoUrl.split('/');
+  let index = 1;
+  const repoName = results[results.length - index];
+  index += 1;
+  const repoOwner = results[results.length - index];
+  if (provider === 'github') {
     try {
-      const client = gitHubApi.client(body.repoToken);
-      const ghrepo = client.repo(`${body.repoOwner}/${body.repoName}`);
+      const client = gitHubApi.client(copilot.accessToken);
+      const ghrepo = client.repo(`${repoOwner}/${repoName}`);
       await new Promise((resolve, reject) => {
         ghrepo.hook({
           name: 'web',
@@ -202,7 +233,7 @@ async function createHook(body) {
           config: {
             url: `${config.HOOK_BASE_URL}/webhooks/github`,
             content_type: 'json',
-            secret: projectDetail.secretWebhookKey,
+            secret: dbProject.secretWebhookKey,
           },
         }, (error) => {
           if (error) {
@@ -221,9 +252,9 @@ async function createHook(body) {
     try {
       const client = new Gitlab({
         url: config.GITLAB_API_BASE_URL,
-        oauthToken: body.repoToken,
+        oauthToken: copilot.accessToken,
       });
-      await client.ProjectHooks.add(`${body.repoOwner}/${body.repoName}`,
+      await client.ProjectHooks.add(`${repoOwner}/${repoName}`,
         `${config.HOOK_BASE_URL}/webhooks/gitlab`, {
           push_events: true,
           issues_events: true,
@@ -234,7 +265,7 @@ async function createHook(body) {
           job_events: true,
           pipeline_events: true,
           wiki_page_events: true,
-          token: projectDetail.secretWebhookKey,
+          token: dbProject.secretWebhookKey,
         }
       );
     } catch (err) {
@@ -244,15 +275,7 @@ async function createHook(body) {
   return { success: true }
 }
 
-createHook.schema = Joi.object().keys({
-  body: Joi.object().keys({
-    projectId: Joi.string().required(),
-    repoType: Joi.string().required(),
-    repoOwner: Joi.string().required(),
-    repoToken: Joi.string().required(),
-    repoName: Joi.string().required(),
-  }),
-});
+createHook.schema = createLabel.schema;
 
 module.exports = {
   create,