API calls added for live matches

This commit is contained in:
Lucas Patenaude
2024-04-03 22:05:41 -06:00
parent 31b84e44f7
commit 3a87b22d17
16 changed files with 249 additions and 102 deletions

View File

@@ -12,6 +12,7 @@ const bodyParser = require('body-parser');
const session = require('express-session'); // To set the session object. To store or access session data, use the `req.session`, which is (generally) serialized as JSON by the store.
const bcrypt = require('bcryptjs'); // To hash passwords
const axios = require('axios'); // To make HTTP requests from our server. We'll learn more about it in Part C.
const moment = require('moment'); // To extract current time data
// *****************************************************
// <!-- Section 2 : Connect to DB -->
@@ -152,14 +153,66 @@ app.get('/', (req, res) => {
});
/************************
Discover Page Routes
Scoreboard Header Routes
*************************/
// Render registration page for /register route
app.get('/home', (req, res) => {
res.render('pages/home');
// Connect to Premier League Matches API
// Define a middleware function to fetch Premier League matches data
app.get('/home', async (req, res) => {
try
{
const today = moment().format('YYYY-MM-DD'); // Get today's date in YYYY-MM-DD format
const response = await axios({
url: 'http://api.football-data.org/v4/competitions/2021/matches',
method: 'GET',
params:
{
dateFrom: '2024-04-03', // Set dateFrom to today's date
dateTo: today // Set dateTo to today's date
},
headers:
{
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3' // Add your API key here
}
});
// Log the response data
// console.log('API Response:', response.data);
const matches = response.data.matches.map(match => {
let homeScore, awayScore, minute;
// Log match data
console.log('Match Data:', {
homeTeam: {
name: match.homeTeam.name,
crest: match.homeTeam.crest,
},
awayTeam: {
name: match.awayTeam.name,
crest: match.awayTeam.crest,
},
score: {
homeScore: match.score.fullTime.home,
awayScore: match.score.fullTime.away,
},
minute: match.status // Set the minute of the game
});
});
// Render the Homepage
res.render('pages/home');
}
catch (error)
{
console.error('Error fetching Premier League matches:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// *****************************************************
// <!-- Section 5 : Start Server-->

View File

@@ -343,8 +343,9 @@
}
},
"node_modules/cookie": {
"version": "0.5.0",
"license": "MIT",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
@@ -468,15 +469,16 @@
}
},
"node_modules/express": {
"version": "4.18.3",
"license": "MIT",
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -618,14 +620,15 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.5",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -1160,6 +1163,14 @@
"node": ">=10"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.0.0",
"license": "MIT"

View File

@@ -1,16 +1,21 @@
0.6.0 / 2023-11-06
==================
* Add `partitioned` option
0.5.0 / 2022-04-11
==================
* Add `priority` option
* Fix `expires` option to reject invalid dates
* pref: improve default decode speed
* pref: remove slow string split in parse
* perf: improve default decode speed
* perf: remove slow string split in parse
0.4.2 / 2022-02-02
==================
* pref: read value only when assigning in parse
* pref: remove unnecessary regexp in parse
* perf: read value only when assigning in parse
* perf: remove unnecessary regexp in parse
0.4.1 / 2020-04-21
==================
@@ -41,7 +46,7 @@
* perf: enable strict mode
* perf: use for loop in parse
* perf: use string concatination for serialization
* perf: use string concatenation for serialization
0.2.3 / 2015-10-25
==================

View File

@@ -2,9 +2,9 @@
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][ci-image]][ci-url]
[![Coverage Status][coveralls-image]][coveralls-url]
Basic HTTP cookie parser and serializer for HTTP servers.
@@ -107,6 +107,17 @@ The given number will be converted to an integer by rounding down. By default, n
`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
so if both are set, they should point to the same date and time.
##### partitioned
Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the
`Partitioned` attribute is not set.
**note** This is an attribute that has not yet been fully standardized, and may change in the future.
This also means many clients may ignore this attribute until they understand it.
More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
##### path
Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path
@@ -212,49 +223,52 @@ $ npm test
```
$ npm run bench
> cookie@0.4.2 bench
> cookie@0.5.0 bench
> node benchmark/index.js
node@16.14.0
v8@9.4.146.24-node.20
uv@1.43.0
zlib@1.2.11
node@18.18.2
acorn@8.10.0
ada@2.6.0
ares@1.19.1
brotli@1.0.9
ares@1.18.1
modules@93
nghttp2@1.45.1
napi@8
llhttp@6.0.4
openssl@1.1.1m+quic
cldr@40.0
icu@70.1
tz@2021a3
unicode@14.0
ngtcp2@0.1.0-DEV
nghttp3@0.1.0-DEV
cldr@43.1
icu@73.2
llhttp@6.0.11
modules@108
napi@9
nghttp2@1.57.0
nghttp3@0.7.0
ngtcp2@0.8.1
openssl@3.0.10+quic
simdutf@3.2.14
tz@2023c
undici@5.26.3
unicode@15.0
uv@1.44.2
uvwasi@0.0.18
v8@10.2.154.26-node.26
zlib@1.2.13.1-motley
> node benchmark/parse-top.js
cookie.parse - top sites
15 tests completed.
14 tests completed.
parse accounts.google.com x 2,421,245 ops/sec ±0.80% (188 runs sampled)
parse apple.com x 2,684,710 ops/sec ±0.59% (189 runs sampled)
parse cloudflare.com x 2,231,418 ops/sec ±0.76% (186 runs sampled)
parse docs.google.com x 2,316,357 ops/sec ±1.28% (187 runs sampled)
parse drive.google.com x 2,363,543 ops/sec ±0.49% (189 runs sampled)
parse en.wikipedia.org x 839,414 ops/sec ±0.53% (189 runs sampled)
parse linkedin.com x 553,797 ops/sec ±0.63% (190 runs sampled)
parse maps.google.com x 1,314,779 ops/sec ±0.72% (189 runs sampled)
parse microsoft.com x 153,783 ops/sec ±0.53% (190 runs sampled)
parse play.google.com x 2,249,574 ops/sec ±0.59% (187 runs sampled)
parse plus.google.com x 2,258,682 ops/sec ±0.60% (188 runs sampled)
parse sites.google.com x 2,247,069 ops/sec ±0.68% (189 runs sampled)
parse support.google.com x 1,456,840 ops/sec ±0.70% (187 runs sampled)
parse www.google.com x 1,046,028 ops/sec ±0.58% (188 runs sampled)
parse youtu.be x 937,428 ops/sec ±1.47% (190 runs sampled)
parse youtube.com x 963,878 ops/sec ±0.59% (190 runs sampled)
parse accounts.google.com x 2,588,913 ops/sec ±0.74% (186 runs sampled)
parse apple.com x 2,370,002 ops/sec ±0.69% (186 runs sampled)
parse cloudflare.com x 2,213,102 ops/sec ±0.88% (188 runs sampled)
parse docs.google.com x 2,194,157 ops/sec ±1.03% (184 runs sampled)
parse drive.google.com x 2,265,084 ops/sec ±0.79% (187 runs sampled)
parse en.wikipedia.org x 457,099 ops/sec ±0.81% (186 runs sampled)
parse linkedin.com x 504,407 ops/sec ±0.89% (186 runs sampled)
parse maps.google.com x 1,230,959 ops/sec ±0.98% (186 runs sampled)
parse microsoft.com x 926,294 ops/sec ±0.88% (184 runs sampled)
parse play.google.com x 2,311,338 ops/sec ±0.83% (185 runs sampled)
parse support.google.com x 1,508,850 ops/sec ±0.86% (186 runs sampled)
parse www.google.com x 1,022,582 ops/sec ±1.32% (182 runs sampled)
parse youtu.be x 332,136 ops/sec ±1.02% (185 runs sampled)
parse youtube.com x 323,833 ops/sec ±0.77% (183 runs sampled)
> node benchmark/parse.js
@@ -262,12 +276,12 @@ $ npm run bench
6 tests completed.
simple x 2,745,604 ops/sec ±0.77% (185 runs sampled)
decode x 557,287 ops/sec ±0.60% (188 runs sampled)
unquote x 2,498,475 ops/sec ±0.55% (189 runs sampled)
duplicates x 868,591 ops/sec ±0.89% (187 runs sampled)
10 cookies x 306,745 ops/sec ±0.49% (190 runs sampled)
100 cookies x 22,414 ops/sec ±2.38% (182 runs sampled)
simple x 3,214,032 ops/sec ±1.61% (183 runs sampled)
decode x 587,237 ops/sec ±1.16% (187 runs sampled)
unquote x 2,954,618 ops/sec ±1.35% (183 runs sampled)
duplicates x 857,008 ops/sec ±0.89% (187 runs sampled)
10 cookies x 292,133 ops/sec ±0.89% (187 runs sampled)
100 cookies x 22,610 ops/sec ±0.68% (187 runs sampled)
```
## References
@@ -275,6 +289,7 @@ $ npm run bench
- [RFC 6265: HTTP State Management Mechanism][rfc-6265]
- [Same-site Cookies][rfc-6265bis-09-5.4.7]
[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
[rfc-6265bis-09-5.4.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7
[rfc-6265]: https://tools.ietf.org/html/rfc6265
@@ -291,12 +306,12 @@ $ npm run bench
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/jshttp/cookie/master?label=ci
[ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master
[coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/cookie/ci/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml
[node-version-image]: https://badgen.net/npm/node/cookie
[node-version-url]: https://nodejs.org/en/download
[node-image]: https://badgen.net/npm/node/cookie
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/cookie
[npm-url]: https://npmjs.org/package/cookie
[npm-version-image]: https://badgen.net/npm/v/cookie

View File

@@ -172,6 +172,10 @@ function serialize(name, val, options) {
str += '; Secure';
}
if (opt.partitioned) {
str += '; Partitioned'
}
if (opt.priority) {
var priority = typeof opt.priority === 'string'
? opt.priority.toLowerCase()
@@ -233,7 +237,7 @@ function decode (str) {
/**
* URL-encode value.
*
* @param {string} str
* @param {string} val
* @returns {string}
*/

View File

@@ -1,7 +1,7 @@
{
"name": "cookie",
"description": "HTTP server cookie parsing and serialization",
"version": "0.5.0",
"version": "0.6.0",
"author": "Roman Shtylman <shtylman@gmail.com>",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
@@ -15,12 +15,12 @@
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "2.1.4",
"eslint": "7.32.0",
"eslint-plugin-markdown": "2.2.1",
"mocha": "9.2.2",
"eslint": "8.53.0",
"eslint-plugin-markdown": "3.0.1",
"mocha": "10.2.0",
"nyc": "15.1.0",
"safe-buffer": "5.2.1",
"top-sites": "1.1.97"
"top-sites": "1.1.194"
},
"files": [
"HISTORY.md",

View File

@@ -1,4 +1,20 @@
4.18.3 / 2024-02-26
4.19.2 / 2024-03-25
==========
* Improved fix for open redirect allow list bypass
4.19.1 / 2024-03-20
==========
* Allow passing non-strings to res.location with new encoding handling checks
4.19.0 / 2024-03-20
==========
* Prevent open redirect allow list bypass due to encodeurl
* deps: cookie@0.6.0
4.18.3 / 2024-02-29
==========
* Fix routing requests without method
@@ -6,6 +22,8 @@
- Fix strict json error message on Node.js 19+
- deps: content-type@~1.0.5
- deps: raw-body@2.5.2
* deps: cookie@0.6.0
- Add `partitioned` option
4.18.2 / 2022-10-08
===================

View File

@@ -55,6 +55,7 @@ module.exports = res
*/
var charsetRegExp = /;\s*charset\s*=/;
var schemaAndHostRegExp = /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?\/\/[^\\\/\?]+/;
/**
* Set status `code`.
@@ -904,15 +905,23 @@ res.cookie = function (name, value, options) {
*/
res.location = function location(url) {
var loc = url;
var loc;
// "back" is an alias for the referrer
if (url === 'back') {
loc = this.req.get('Referrer') || '/';
} else {
loc = String(url);
}
// set location
return this.set('Location', encodeUrl(loc));
var m = schemaAndHostRegExp.exec(loc);
var pos = m ? m[0].length + 1 : 0;
// Only encode after host to avoid invalid encoding which can introduce
// vulnerabilities (e.g. `\\` to `%5C`).
loc = loc.slice(0, pos) + encodeUrl(loc.slice(pos));
return this.set('Location', loc);
};
/**

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "4.18.3",
"version": "4.19.2",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
@@ -33,7 +33,7 @@
"body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",

View File

@@ -461,7 +461,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
redirectUrl.protocol !== "https:" ||
redirectUrl.host !== currentHost &&
!isSubdomain(redirectUrl.host, currentHost)) {
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback

View File

@@ -1,6 +1,6 @@
{
"name": "follow-redirects",
"version": "1.15.5",
"version": "1.15.6",
"description": "HTTP and HTTPS modules that follow redirects.",
"license": "MIT",
"main": "index.js",

View File

@@ -13,6 +13,7 @@
"express": "^4.6.1",
"express-handlebars": "^7.1.2",
"express-session": "1.17.3",
"moment": "^2.30.1",
"nodemon": "2.0.20",
"pg-promise": "^10.11.1"
}
@@ -357,8 +358,9 @@
}
},
"node_modules/cookie": {
"version": "0.5.0",
"license": "MIT",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
@@ -482,15 +484,16 @@
}
},
"node_modules/express": {
"version": "4.18.3",
"license": "MIT",
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -632,14 +635,15 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.5",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -1174,6 +1178,14 @@
"node": ">=10"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.0.0",
"license": "MIT"

View File

@@ -9,6 +9,7 @@
"express": "^4.6.1",
"express-handlebars": "^7.1.2",
"express-session": "1.17.3",
"moment": "^2.30.1",
"nodemon": "2.0.20",
"pg-promise": "^10.11.1"
},

View File

@@ -5,13 +5,15 @@
<div class="left-side">
<!-- Team 1 Name with Score -->
<div class="team">
<p id="team-name">Arsenal</p> <!-- {{team1.name}} -->
<p id="team-score">0</p>
<p id="team-crest">{{ homeTeam.crest }}</p>
<p id="team-name">{{ homeTeam.name }}</p> <!-- {{team1.name}} -->
<p id="team-score">{{ homeTeam.score }}</p>
</div>
<!-- Team 2 Name with Score -->
<div class="team">
<p id="team-name">Liverpool</p> <!-- {{team2.name}} -->
<p id="team-score">1</p>
<p id="team-crest">{{ awayTeam.crest }}</p>
<p id="team-name">{{ awayTeam.name }}</p> <!-- {{team1.name}} -->
<p id="team-score">{{ awayTeam.score }}</p>
</div>
</div>
@@ -19,7 +21,7 @@
<div class="right-side">
<!-- Time -->
<div class="score" style="text-align: center;">
<p id="time">94'</p>
<p id="time">{{ minute }}</p>
</div>
</div>

View File

@@ -1,14 +1,31 @@
<div class="scoreboard-container" id="scoreboard">
<div class="scoreboard-league-container">
{{#each matches}}
<div class="card" id="game-card">
<div class="score-card-body">
<!-- Insert a game card -->
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
{{> scoreboard-header/game-card}}
<!-- Left side (70%) -->
<div class="left-side">
<!-- Team 1 Name with Score -->
<div class="team">
<p id="team-crest">{{ homeTeam.crest }}</p>
<p id="team-name">{{ homeTeam.name }}</p> <!-- {{team1.name}} -->
<p id="team-score">{{ homeTeam.score }}</p>
</div>
<!-- Team 2 Name with Score -->
<div class="team">
<p id="team-crest">{{ awayTeam.crest }}</p>
<p id="team-name">{{ awayTeam.name }}</p> <!-- {{team1.name}} -->
<p id="team-score">{{ awayTeam.score }}</p>
</div>
</div>
<!-- Right side (30%) -->
<div class="right-side">
<!-- Time -->
<div class="score" style="text-align: center;">
<p id="time">{{ minute }}</p>
</div>
</div>
</div>
</div>
{{/each}}