Mukho

Add IP address in log

......@@ -122,6 +122,7 @@ io.sockets.on('connection', function(socket) {
})
})
server.listen(PORT, function(){
// 서버 가동(IPv4 형식으로 express 설정)
server.listen(PORT, '127.0.0.1', function(){
console.log(logString+"서버가 시작되었습니다.(Port: "+PORT+")");
});
\ No newline at end of file
......
The MIT License (MIT)
Copyright (c) 2014-2016 Aras Atasaygin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
{
"_from": "is_js@^0.9.0",
"_id": "is_js@0.9.0",
"_inBundle": false,
"_integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=",
"_location": "/is_js",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "is_js@^0.9.0",
"name": "is_js",
"escapedName": "is_js",
"rawSpec": "^0.9.0",
"saveSpec": null,
"fetchSpec": "^0.9.0"
},
"_requiredBy": [
"/request-ip"
],
"_resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
"_shasum": "0ab94540502ba7afa24c856aa985561669e9c52d",
"_spec": "is_js@^0.9.0",
"_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer\\node_modules\\request-ip",
"bugs": {
"url": "https://github.com/arasatasaygin/is.js/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "micro check library",
"devDependencies": {
"chai": "^3.4.0",
"eslint": "^2.13.1",
"lodash": "^4.15.0",
"mocha": "^2.2.1",
"mocha-phantomjs": "^4.1.0",
"pre-commit": "^1.1.3",
"uglify-js": "^2.7.3"
},
"files": [
"is.js",
"is.min.js"
],
"homepage": "http://is.js.org/",
"license": "MIT",
"main": "is.js",
"name": "is_js",
"pre-commit": [
"lint"
],
"repository": {
"type": "git",
"url": "git+https://github.com/arasatasaygin/is.js.git"
},
"scripts": {
"build": "npm run lint && npm run min",
"lint": "eslint .",
"min": "uglifyjs is.js -m --comments \"/^!/\" -o is.min.js",
"test": "mocha --check-leaks -R dot",
"test:phantom": "mocha-phantomjs -R dot test/index.html"
},
"version": "0.9.0"
}
# Change Log
## [2.1.2](https://github.com/pbojinov/request-ip/tree/2.1.2) (2018-10-29)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.1...2.1.2)
**Closed issues:**
- Handle Firebase hosting header fastly-client-ip [\#37](https://github.com/pbojinov/request-ip/issues/37)
**Merged pull requests:**
- chore: improve packaging [\#40](https://github.com/pbojinov/request-ip/pull/40) ([pi0](https://github.com/pi0))
- fixed Cannot redefine property: clientIp error [\#39](https://github.com/pbojinov/request-ip/pull/39) ([karankohli13](https://github.com/karankohli13))
- Add firebase hosting header [\#38](https://github.com/pbojinov/request-ip/pull/38) ([vishalvijay](https://github.com/vishalvijay))
## [2.1.1](https://github.com/pbojinov/request-ip/tree/2.1.1) (2018-07-03)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.0...2.1.1)
## [2.1.0](https://github.com/pbojinov/request-ip/tree/2.1.0) (2018-07-03)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.2...2.1.0)
**Closed issues:**
- Not getting the right ip first time [\#28](https://github.com/pbojinov/request-ip/issues/28)
- Allow using node \> 6 [\#27](https://github.com/pbojinov/request-ip/issues/27)
**Merged pull requests:**
- Get client ip when using AWS Api Gateway + Lambda. [\#35](https://github.com/pbojinov/request-ip/pull/35) ([rafaelthemendes](https://github.com/rafaelthemendes))
- redefine attribute getter [\#34](https://github.com/pbojinov/request-ip/pull/34) ([isayme](https://github.com/isayme))
## [2.0.2](https://github.com/pbojinov/request-ip/tree/2.0.2) (2017-06-26)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.1...2.0.2)
**Closed issues:**
- azure web app adds port to x-forwarded-for [\#29](https://github.com/pbojinov/request-ip/issues/29)
**Merged pull requests:**
- handling x-forwarded-for with ip:port [\#30](https://github.com/pbojinov/request-ip/pull/30) ([luisrudge](https://github.com/luisrudge))
## [2.0.1](https://github.com/pbojinov/request-ip/tree/2.0.1) (2017-03-09)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.0...2.0.1)
**Implemented enhancements:**
- ES2015 Support [\#22](https://github.com/pbojinov/request-ip/issues/22)
## [2.0.0](https://github.com/pbojinov/request-ip/tree/2.0.0) (2017-03-07)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.3.0...2.0.0)
**Closed issues:**
- optimized your code a bit \(no need to evalutate every option before choosing first one that matches. just evaluate then return on first match\) [\#15](https://github.com/pbojinov/request-ip/issues/15)
**Merged pull requests:**
- Refactor to ES6 [\#23](https://github.com/pbojinov/request-ip/pull/23) ([fluxsauce](https://github.com/fluxsauce))
## [1.3.0](https://github.com/pbojinov/request-ip/tree/1.3.0) (2017-03-03)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.3...1.3.0)
**Closed issues:**
- Support Cloudflare? [\#20](https://github.com/pbojinov/request-ip/issues/20)
- How to receive IP in client [\#17](https://github.com/pbojinov/request-ip/issues/17)
**Merged pull requests:**
- Adding support for CF-Connecting-IP and True-Client-IP [\#21](https://github.com/pbojinov/request-ip/pull/21) ([fluxsauce](https://github.com/fluxsauce))
- Return once we find something and don't crash if req.headers is undefined [\#19](https://github.com/pbojinov/request-ip/pull/19) ([rokob](https://github.com/rokob))
- Ignore 'unknown' ip addresses in X-Forwarded-For header [\#18](https://github.com/pbojinov/request-ip/pull/18) ([raunc](https://github.com/raunc))
## [1.2.3](https://github.com/pbojinov/request-ip/tree/1.2.3) (2016-11-02)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.2...1.2.3)
**Closed issues:**
- Are there any security concerns when saving the IP directly to a database? [\#16](https://github.com/pbojinov/request-ip/issues/16)
- I'm not getting local host ip address 127.0.0.1 [\#14](https://github.com/pbojinov/request-ip/issues/14)
## [1.2.2](https://github.com/pbojinov/request-ip/tree/1.2.2) (2016-01-27)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.1...1.2.2)
## [1.2.1](https://github.com/pbojinov/request-ip/tree/1.2.1) (2016-01-27)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.0...1.2.1)
**Merged pull requests:**
- introduce a built-in default implementation for a connect-middleware [\#12](https://github.com/pbojinov/request-ip/pull/12) ([osherx](https://github.com/osherx))
## [1.2.0](https://github.com/pbojinov/request-ip/tree/1.2.0) (2016-01-27)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.4...1.2.0)
**Merged pull requests:**
- Cleanup [\#13](https://github.com/pbojinov/request-ip/pull/13) ([minecrawler](https://github.com/minecrawler))
- Got it working in a case that was returning null [\#11](https://github.com/pbojinov/request-ip/pull/11) ([andfaulkner](https://github.com/andfaulkner))
## [1.1.4](https://github.com/pbojinov/request-ip/tree/1.1.4) (2015-07-23)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.3...1.1.4)
**Merged pull requests:**
- Add case management where you can not find the IP address [\#10](https://github.com/pbojinov/request-ip/pull/10) ([sitexw](https://github.com/sitexw))
## [1.1.3](https://github.com/pbojinov/request-ip/tree/1.1.3) (2015-04-20)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.2...1.1.3)
## [1.1.2](https://github.com/pbojinov/request-ip/tree/1.1.2) (2015-04-04)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.1...1.1.2)
## [1.1.1](https://github.com/pbojinov/request-ip/tree/1.1.1) (2015-04-04)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.0...1.1.1)
**Closed issues:**
- needs semver [\#7](https://github.com/pbojinov/request-ip/issues/7)
## [1.1.0](https://github.com/pbojinov/request-ip/tree/1.1.0) (2015-04-04)
[Full Changelog](https://github.com/pbojinov/request-ip/compare/v0.0.4...1.1.0)
**Merged pull requests:**
- Update README.md [\#9](https://github.com/pbojinov/request-ip/pull/9) ([coolaj86](https://github.com/coolaj86))
- This deserves a production version number. [\#8](https://github.com/pbojinov/request-ip/pull/8) ([coolaj86](https://github.com/coolaj86))
## [v0.0.4](https://github.com/pbojinov/request-ip/tree/v0.0.4) (2015-01-16)
**Closed issues:**
- Invalid header [\#5](https://github.com/pbojinov/request-ip/issues/5)
- replace req.header\('X-Forwarded-For'\) for req.header\('X-Forwarder-For'\)\); [\#3](https://github.com/pbojinov/request-ip/issues/3)
- Nginx problems [\#2](https://github.com/pbojinov/request-ip/issues/2)
**Merged pull requests:**
- Add support for X-Real-IP Header [\#6](https://github.com/pbojinov/request-ip/pull/6) ([pmarques](https://github.com/pmarques))
- fix bug X-Forwarder-For [\#4](https://github.com/pbojinov/request-ip/pull/4) ([morello-cl](https://github.com/morello-cl))
- Add a Bitdeli Badge to README [\#1](https://github.com/pbojinov/request-ip/pull/1) ([bitdeli-chef](https://github.com/bitdeli-chef))
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
The MIT License (MIT)
Copyright (c) 2018 Petar Bojinov - petarbojinov@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# request-ip
A tiny Node.js module for retrieving a request's IP address.
![](https://nodei.co/npm/request-ip.png?downloads=true&cacheBust=2)
![](https://travis-ci.org/pbojinov/request-ip.svg?branch=master)
[![Coverage Status](https://coveralls.io/repos/pbojinov/request-ip/badge.svg)](https://coveralls.io/r/pbojinov/request-ip)
![](https://img.shields.io/npm/l/express.svg)
[![npm version](https://badge.fury.io/js/request-ip.svg)](https://badge.fury.io/js/request-ip)
## Installation
```bash
npm install request-ip --save
```
## Getting Started
```javascript
const requestIp = require('request-ip');
// inside middleware handler
const ipMiddleware = function(req, res, next) {
const clientIp = requestIp.getClientIp(req);
next();
};
// on localhost you'll see 127.0.0.1 if you're using IPv4
// or ::1, ::ffff:127.0.0.1 if you're using IPv6
```
### As Connect Middleware
```javascript
const requestIp = require('request-ip');
app.use(requestIp.mw())
app.use(function(req, res) {
const ip = req.clientIp;
res.end(ip);
});
```
To see a full working code for the middleware, check out the [examples](https://github.com/pbojinov/request-ip/tree/master/examples) folder.
The connect-middleware also supports retrieving the ip address under a custom attribute name, which also works as a container for any future settings.
## How It Works
It looks for specific headers in the request and falls back to some defaults if they do not exist.
The user ip is determined by the following order:
1. `X-Client-IP`
2. `X-Forwarded-For` (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.)
3. `CF-Connecting-IP` (Cloudflare)
4. `Fastly-Client-Ip` (Fastly CDN and Firebase hosting header when forwared to a cloud function)
5. `True-Client-Ip` (Akamai and Cloudflare)
6. `X-Real-IP` (Nginx proxy/FastCGI)
7. `X-Cluster-Client-IP` (Rackspace LB, Riverbed Stingray)
8. `X-Forwarded`, `Forwarded-For` and `Forwarded` (Variations of #2)
9. `req.connection.remoteAddress`
10. `req.socket.remoteAddress`
11. `req.connection.socket.remoteAddress`
12. `req.info.remoteAddress`
If an IP address cannot be found, it will return `null`.
## Samples Use Cases
* Getting a user's IP for geolocation.
## Running the Tests
Make sure you have the necessary dev dependencies needed to run the tests:
```
npm install
```
Run the integration tests
```
npm test
```
## Release Notes
See the wonderful [changelog](https://github.com/pbojinov/request-ip/blob/master/CHANGELOG.md)
To easily generate a new changelog, install [github-changelog-generator](https://github.com/skywinder/github-changelog-generator) then run `npm run changelog`.
## Contributors
* Thanks to [@osherx](https://github.com/osherx) for adding the connect-middleware.
* Thanks to [@raunc](https://github.com/raunc) for adding Squid proxy support.
* Thanks to [@fluxsauce](https://github.com/fluxsauce) for adding `CF-Connecting-IP`, `True-Client-IP`, and ES6 support.
* Thanks to [@vishalvijay](https://github.com/vishalvijay) for adding Fastly/Firebase hosting support.
## License
The MIT License (MIT) - 2018
No preview for this file type
"use strict";
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var is = require('is_js');
/**
* Parse x-forwarded-for headers.
*
* @param {string} value - The value to be parsed.
* @return {string|null} First known IP address, if any.
*/
function getClientIpFromXForwardedFor(value) {
if (!is.existy(value)) {
return null;
}
if (is.not.string(value)) {
throw new TypeError("Expected a string, got \"".concat(_typeof(value), "\""));
} // x-forwarded-for may return multiple IP addresses in the format:
// "client IP, proxy 1 IP, proxy 2 IP"
// Therefore, the right-most IP address is the IP address of the most recent proxy
// and the left-most IP address is the IP address of the originating client.
// source: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
// Azure Web App's also adds a port for some reason, so we'll only use the first part (the IP)
var forwardedIps = value.split(',').map(function (e) {
var ip = e.trim();
if (ip.includes(':')) {
var splitted = ip.split(':'); // make sure we only use this if it's ipv4 (ip:port)
if (splitted.length === 2) {
return splitted[0];
}
}
return ip;
}); // Sometimes IP addresses in this header can be 'unknown' (http://stackoverflow.com/a/11285650).
// Therefore taking the left-most IP address that is not unknown
// A Squid configuration directive can also set the value to "unknown" (http://www.squid-cache.org/Doc/config/forwarded_for/)
return forwardedIps.find(is.ip);
}
/**
* Determine client IP address.
*
* @param req
* @returns {string} ip - The IP address if known, defaulting to empty string if unknown.
*/
function getClientIp(req) {
// Server is probably behind a proxy.
if (req.headers) {
// Standard headers used by Amazon EC2, Heroku, and others.
if (is.ip(req.headers['x-client-ip'])) {
return req.headers['x-client-ip'];
} // Load-balancers (AWS ELB) or proxies.
var xForwardedFor = getClientIpFromXForwardedFor(req.headers['x-forwarded-for']);
if (is.ip(xForwardedFor)) {
return xForwardedFor;
} // Cloudflare.
// @see https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
// CF-Connecting-IP - applied to every request to the origin.
if (is.ip(req.headers['cf-connecting-ip'])) {
return req.headers['cf-connecting-ip'];
} // Fastly and Firebase hosting header (When forwared to cloud function)
if (is.ip(req.headers['fastly-client-ip'])) {
return req.headers['fastly-client-ip'];
} // Akamai and Cloudflare: True-Client-IP.
if (is.ip(req.headers['true-client-ip'])) {
return req.headers['true-client-ip'];
} // Default nginx proxy/fcgi; alternative to x-forwarded-for, used by some proxies.
if (is.ip(req.headers['x-real-ip'])) {
return req.headers['x-real-ip'];
} // (Rackspace LB and Riverbed's Stingray)
// http://www.rackspace.com/knowledge_center/article/controlling-access-to-linux-cloud-sites-based-on-the-client-ip-address
// https://splash.riverbed.com/docs/DOC-1926
if (is.ip(req.headers['x-cluster-client-ip'])) {
return req.headers['x-cluster-client-ip'];
}
if (is.ip(req.headers['x-forwarded'])) {
return req.headers['x-forwarded'];
}
if (is.ip(req.headers['forwarded-for'])) {
return req.headers['forwarded-for'];
}
if (is.ip(req.headers.forwarded)) {
return req.headers.forwarded;
}
} // Remote address checks.
if (is.existy(req.connection)) {
if (is.ip(req.connection.remoteAddress)) {
return req.connection.remoteAddress;
}
if (is.existy(req.connection.socket) && is.ip(req.connection.socket.remoteAddress)) {
return req.connection.socket.remoteAddress;
}
}
if (is.existy(req.socket) && is.ip(req.socket.remoteAddress)) {
return req.socket.remoteAddress;
}
if (is.existy(req.info) && is.ip(req.info.remoteAddress)) {
return req.info.remoteAddress;
} // AWS Api Gateway + Lambda
if (is.existy(req.requestContext) && is.existy(req.requestContext.identity) && is.ip(req.requestContext.identity.sourceIp)) {
return req.requestContext.identity.sourceIp;
}
return null;
}
/**
* Expose request IP as a middleware.
*
* @param {object} [options] - Configuration.
* @param {string} [options.attributeName] - Name of attribute to augment request object with.
* @return {*}
*/
function mw(options) {
// Defaults.
var configuration = is.not.existy(options) ? {} : options; // Validation.
if (is.not.object(configuration)) {
throw new TypeError('Options must be an object!');
}
var attributeName = configuration.attributeName || 'clientIp';
return function (req, res, next) {
var ip = getClientIp(req);
Object.defineProperty(req, attributeName, {
get: function get() {
return ip;
},
configurable: true
});
next();
};
}
module.exports = {
getClientIpFromXForwardedFor: getClientIpFromXForwardedFor,
getClientIp: getClientIp,
mw: mw
};
{
"_from": "request-ip",
"_id": "request-ip@2.1.3",
"_inBundle": false,
"_integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==",
"_location": "/request-ip",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "request-ip",
"name": "request-ip",
"escapedName": "request-ip",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz",
"_shasum": "99ab2bafdeaf2002626e28083cb10597511d9e14",
"_spec": "request-ip",
"_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer",
"author": {
"name": "Petar Bojinov",
"email": "petarbojinov@gmail.com"
},
"bugs": {
"url": "https://github.com/pbojinov/request-ip/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Jon Peck",
"email": "jpeck@fluxsauce.com"
}
],
"dependencies": {
"is_js": "^0.9.0"
},
"deprecated": false,
"description": "A small node.js module to retrieve the request's IP address",
"devDependencies": {
"@babel/cli": "^7.0.0-beta.51",
"@babel/core": "^7.0.0-beta.51",
"@babel/preset-env": "^7.0.0-beta.51",
"coveralls": "^3.0.2",
"eslint": "^5.8.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.2.0",
"nyc": "^13.1.0",
"request": "^2.54.0",
"tap-spec": "^5.0.0",
"tape": "^4.9.1"
},
"files": [
"dist"
],
"homepage": "https://github.com/pbojinov/request-ip",
"keywords": [
"request ip",
"ip",
"address",
"request",
"proxy",
"client",
"header",
"X-Client-IP",
"X-Forwarded-For",
"CF-Connecting-IP",
"Fastly-Client-IP",
"True-Client-IP",
"X-Real-IP",
"X-Cluster-Client-IP",
"X-Forwarded",
"Forwarded-For",
"connection.remoteAddress",
"connection.socket.remoteAddress",
"req.info.remoteAddress",
"middleware",
"ipv4",
"ipv6"
],
"license": "MIT",
"main": "./dist/index.js",
"name": "request-ip",
"repository": {
"type": "git",
"url": "git+https://github.com/pbojinov/request-ip.git"
},
"scripts": {
"build": "babel ./src/index.js > ./dist/index.js",
"changelog": "github_changelog_generator -u pbojinov -p request-ip",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"test": "nyc --reporter=html --reporter=text --check-coverage --lines=100 --statements=100 tape ./test/index.js"
},
"version": "2.1.3"
}
......@@ -750,6 +750,11 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
"is_js": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
"integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
......@@ -1154,6 +1159,14 @@
}
}
},
"request-ip": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz",
"integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==",
"requires": {
"is_js": "^0.9.0"
}
},
"request-promise-core": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
......
......@@ -12,6 +12,7 @@
"ejs": "^3.1.6",
"express": "^4.17.1",
"mysql": "^2.18.1",
"request-ip": "^2.1.3",
"socket.io": "^4.4.0"
},
"devDependencies": {
......
......@@ -60,10 +60,10 @@ create table board(
>UPDATE board SET idx = @COUNT:=@COUNT+1;
---
### 최종 수정: 2021-11-23 01:53<br>
### 최종 수정: 2021-11-23 02:49<br>
### 수정 내용:
0. 채팅기능에 버그가 있는 것 같음-피드백 바람(undefined님이 나가셨습니다. -> 콘솔에 계속 출력됨)
1. 일부 수정
1. 로그에 IP 추가
2. 로그에 시간 추가
3. 시간 실시간 반영
4. 게시글 수정 및 삭제 세션+권한 연동/DB수정
......
......@@ -2,6 +2,7 @@ var express = require('express')
var app = express()
var router = express.Router();
var path = require('path') // 상대경로
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -24,14 +25,15 @@ init()
// main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
router.get('/', function(req, res){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.')
console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/about.html"))
}
if(id){
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.('+ip+')')
res.render('about.ejs', {'ID': id, 'nickname': nickname});
}
});
......
......@@ -7,6 +7,7 @@ var mysql = require('mysql');
var path = require('path') // 상대경로
var mysql_odbc = require('../../db/db_board')();
var board = mysql_odbc.init();
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -28,9 +29,10 @@ function init(){
init()
router.get('/list/:page', function(req, res, next) {
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.')
console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')')
res.redirect('/board/list/1')
}
else{
......@@ -41,36 +43,39 @@ router.get('/list/:page', function(req, res, next) {
if (err) console.error("err : " + err);
var id = req.user.ID;
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.('+ip+')')
res.render('list.ejs', {'ID':id, 'nickname': nickname, title: '게시판 리스트', rows: rows, page:page, length:rows.length-1,page_num:10,pass:true})
})
}
});
router.get('/list', function(req,res,next){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.')
console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/login.html"))
}
else res.redirect('/board/list/1')
})
router.get('/write', function(req,res,next){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.')
console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/login.html"))
}
else{
var id = req.user.ID;
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.('+ip+')')
res.render('write.ejs', {'ID':id, 'nickname': nickname, title:"게시판 글 쓰기"})
}
})
router.post('/write', function(req,res,next){
var ip = requestIp.getClientIp(req);
var nickname = req.user.nickname // var name = req.body.name
var title = req.body.title
var content = req.body.content
......@@ -91,12 +96,13 @@ router.post('/write', function(req,res,next){
if(!idx_) // 글이 없으면 NULL
idx_ = 1;
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.('+ip+')')
res.redirect('/board/read/'+idx_);
});
})
router.get('/read/:idx', function(req,res,next){
var ip = requestIp.getClientIp(req);
var idx = req.params.idx
var sql = "select idx, nickname, title, content, date_format(modidate,'%Y-%m-%d %H:%i:%s') modidate, " +
"date_format(regdate,'%Y-%m-%d %H:%i:%s') regdate, hit, ID from board where idx=?";
......@@ -105,7 +111,7 @@ router.get('/read/:idx', function(req,res,next){
var id = req.user;
if(!id){
console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.')
console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.('+ip+')')
res.redirect('/login')
}
else{
......@@ -118,13 +124,14 @@ router.get('/read/:idx', function(req,res,next){
if(err) console.error(err)
})
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.('+ip+')')
res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]})
}
})
})
router.post('/update', function(req,res,next){
var ip = requestIp.getClientIp(req);
var ID = req.user.ID;
var idx = req.body.idx
var title = req.body.title
......@@ -135,19 +142,20 @@ router.post('/update', function(req,res,next){
board.query(sql,datas,function(err,result){
if(err) console.error(err)
if(result.affectedRows==0){
console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음)')
console.log(logString+req.user.ID+'('+req.user.nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음 // '+ip+')')
res.send("<script>alert('게시글 작성자가 아닙니다.');history.back();</script>")
}
else{
var id = req.user.ID;
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.('+ip+')')
res.redirect('/board/read/'+idx)
}
})
})
router.post('/delete', function(req,res,next){
var ip = requestIp.getClientIp(req);
var idx = req.body.idx
var ID = req.user.ID;
var datas = [idx,ID]
......@@ -170,12 +178,12 @@ router.post('/delete', function(req,res,next){
var nickname = req.user.nickname;
res.send("<script>alert('게시글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/list/';</script>");
console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.')
console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')')
})
}
else{ // 작성자도, 운영자도 아니면
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음)')
console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음 // '+ip+')')
res.send("<script>alert('게시글 작성자가 아닙니다');history.back();</script>");
}
})
......@@ -184,7 +192,7 @@ router.post('/delete', function(req,res,next){
var id = req.user.ID;
var nickname = req.user.nickname;
res.send("<script>alert('게시글이 삭제되었습니다.');window.location.href='/board/list/';</script>");
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')')
}
})
})
......
......@@ -4,6 +4,7 @@ var router = express.Router();
var path = require('path') // 상대경로
var mysql_odbc = require('../../db/db_board')();
var myinfo = mysql_odbc.init();
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -25,14 +26,15 @@ function init(){
init()
router.get('/', function(req, res){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.')
console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/login.html"))
}
if(id){
var nickname = req.user.nickname
console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.('+ip+')')
res.render('chat.ejs', {'nickname':nickname})
}
});
......
......@@ -2,6 +2,7 @@ var express = require('express')
var app = express()
var router = express.Router();
var path = require('path')
var requestIp = require('request-ip');
var main = require('./main/main')
var register = require('./register/index')
......@@ -12,10 +13,39 @@ var profile = require('./profile/index')
var about = require('./about/index')
var chat = require('./chat/chat')
// 로그용
var logString;
function getTime(){
var today = new Date();
var year = today.getFullYear();
var month = ('0' + (today.getMonth()+1)).slice(-2);
var day = ('0' + today.getDate()).slice(-2);
var hour = ('0' + today.getHours()).slice(-2);
var minute = ('0' + today.getMinutes()).slice(-2);
var second = ('0' + today.getSeconds()).slice(-2);
logString = '['+year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+'] ';
}
// 시간 갱신용
function init(){
getTime();
setInterval(getTime, 1000)
}
init()
// URL routing
// req = request, res = respond
router.get('/', function(req, res){
res.sendFile(path.join(__dirname, "../public/main.html"));
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')')
res.sendFile(path.join(__dirname, "../public/main.html"))
}
if(id){
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')')
res.render('main.ejs', {'ID': id, 'nickname': nickname});
}
});
// router 정의
......
......@@ -5,6 +5,7 @@ var path = require('path') // 상대경로
var mysql = require('mysql')
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -39,7 +40,8 @@ router.get('/', function(req, res){
var msg;
var errMsg = req.flash('error')
if(errMsg) msg = errMsg;
console.log(logString+'익명의 유저가 로그인 중입니다.')
var ip = requestIp.getClientIp(req);
console.log(logString+'익명의 유저가 로그인 중입니다.('+ip+')')
res.render('login.ejs', {'message' : msg});
})
......@@ -62,18 +64,19 @@ passport.use('local-login', new LocalStrategy({
var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){
if(err) return done(err);
var ip = requestIp.getClientIp(req);
if(rows.length){ // database에 입력한 ID값이 있는가?
if(password == rows[0].password){ // 비밀번호와 확인이 같은가?
console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname + ")")
console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname +" // "+ip+')')
return done(null, {'ID' : ID, 'nickname' : rows[0].nickname});
}
else{
console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+")")
console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+" // "+ip+')')
return done(null, false, {message : '잘못된 비밀번호입니다.'})
}
}
else{
console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+")")
console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+" // "+ip+')')
return done(null, false, {message : 'ID를 찾을 수 없습니다.'})
}
})
......
......@@ -2,6 +2,7 @@ var express = require('express')
var app = express()
var router = express.Router();
var path = require('path')
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -23,13 +24,14 @@ function init(){
init()
router.get('/', function(req, res){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.")
console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.("+ip+')')
res.redirect('/main')
}
else{
console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.")
console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.("+ip+')')
req.logout();
req.session.save(function(){
res.redirect('/');
......
......@@ -2,6 +2,7 @@ var express = require('express')
var app = express()
var router = express.Router();
var path = require('path') // 상대경로
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -24,14 +25,15 @@ init()
// main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
router.get('/', function(req, res){
var ip = requestIp.getClientIp(req);
var id = req.user;
if(!id){
console.log(logString+'익명의 유저가 작업 중입니다.')
console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/main.html"))
}
if(id){
var nickname = req.user.nickname;
console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')')
res.render('main.ejs', {'ID': id, 'nickname': nickname});
}
});
......
......@@ -6,6 +6,7 @@ var mysql_odbc = require('../../db/db_board')();
var myinfo = mysql_odbc.init();
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -39,6 +40,7 @@ passport.deserializeUser(function(user, done){
// main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
router.get('/', function(req, res){
var ip = requestIp.getClientIp(req);
try{
var id = req.session.passport.user.ID;
// if(!id){
......@@ -53,18 +55,19 @@ router.get('/', function(req, res){
var nickname = req.user.nickname;
var type = rows[0].type;
var profilemsg = rows[0].profilemsg;
console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.('+ip+')')
res.render('profile.ejs', {'ID':id, 'nickname': nickname, 'type': type, 'profilemsg': profilemsg})
})
}
catch{
console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.')
console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/login.html"))
}
});
router.get('/update', function(req,res){
var ip = requestIp.getClientIp(req);
try{
var id = req.user.ID;
// if(!id){
......@@ -80,19 +83,20 @@ router.get('/update', function(req,res){
var nickname = req.user.nickname;
var type = req.user.type;
var profilemsg = rows[0].profilemsg;
console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.')
console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.('+ip+')')
res.render('profmsgedit.ejs', {'ID':id, 'nickname': nickname, 'type':type, 'profilemsg': profilemsg, 'message':''});
})
}
catch{
if(!id){
console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.')
console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.('+ip+')')
res.sendFile(path.join(__dirname, "../../public/login.html"))
}
}
})
router.post('/update', function(req,res,next){
var ip = requestIp.getClientIp(req);
var id = req.user.ID;
var profilemsg = req.body.profilemsg;
var nickname = req.body.nickname;
......@@ -127,7 +131,7 @@ router.post('/update', function(req,res,next){
myinfo.query(sql,datas,function(err,result){
if(err) console.error(err)
console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.')
console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.('+ip+')')
console.log(" ▷ 변경전: "+id+"("+req.user.nickname+") "+oldType+" // "+oldProfilemsg)
req.session.passport.user.nickname = nickname;
console.log(" ▶ 변경후: "+id+"("+nickname+") "+type+" // "+profilemsg)
......@@ -135,7 +139,7 @@ router.post('/update', function(req,res,next){
})
}
else{ // 다른 유저의 닉네임과 중복되는 경우
console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+")")
console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+" // ("+ip+')')
res.render('profmsgedit.ejs', {nickname: req.session.passport.user.nickname, profilemsg: oldProfilemsg, message : '중복된 닉네임입니다.'})
}
})
......
......@@ -5,6 +5,7 @@ var path = require('path') // 상대경로
var mysql = require('mysql')
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy
var requestIp = require('request-ip');
// 로그용
var logString;
......@@ -39,7 +40,8 @@ router.get('/', function(req, res){
var msg;
var errMsg = req.flash('error')
if(errMsg) msg = errMsg;
console.log(logString+'익명의 유저가 회원가입 중입니다.')
var ip = requestIp.getClientIp(req);
console.log(logString+'익명의 유저가 회원가입 중입니다.('+ip+')')
res.render('register.ejs', {'message' : msg});
})
......@@ -63,29 +65,30 @@ passport.use('local-join', new LocalStrategy({
passReqToCallback: true
}, function(req, ID, password, done){
var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){
var ip = requestIp.getClientIp(req);
if(err) return done(err);
if(rows.length){ // database에 입력한 ID값이 있는가?
console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+")")
console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+" // "+ip+')')
return done(null, false, {message : '중복된 ID입니다.'})
}
else{
if(password != req.body.pw_com){ // 비밀번호와 확인이 같지 않은가?
console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+")")
console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+" // "+ip+')')
return done(null, false, {message : '비밀번호가 일치하지 않습니다.'})
}
else{
var subqry = connection.query('select * from userDB where nickname=?', [req.body.nickname], function(err, rows_){
if(err) return done(err);
if(rows_.length){
console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+")")
console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+" // "+ip+')')
return done(null, false, {message : '중복된 닉네임입니다.'})
}
else{
var sql = {ID: ID, password: password, type:req.body.type, nickname:req.body.nickname};
var query = connection.query('insert into userDB set ?', sql, function(err, rows){
if(err) throw err
console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + ")")
console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + " // "+ip+')')
return done(null, {'ID' : ID, 'nickname' : req.body.nickname});
})
}
......