커밋 테스트

This commit is contained in:
2024-09-09 15:51:39 +09:00
parent c3906dac0d
commit 812da693ec
216 changed files with 30967 additions and 212 deletions

14
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"configurations": [
{
"type": "java",
"name": "Spring Boot-BoardBackApplication<board-back>",
"request": "launch",
"cwd": "${workspaceFolder}",
"mainClass": "com.eogns.board_back.BoardBackApplication",
"projectName": "board-back",
"args": "",
"envFile": "${workspaceFolder}/.env"
}
]
}

View File

@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.18'
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.6'
}
@ -28,6 +28,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'

16
board-back/node_modules/.bin/loose-envify generated vendored Normal file
View File

@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../loose-envify/cli.js" "$@"
else
exec node "$basedir/../loose-envify/cli.js" "$@"
fi

17
board-back/node_modules/.bin/loose-envify.cmd generated vendored Normal file
View File

@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\loose-envify\cli.js" %*

28
board-back/node_modules/.bin/loose-envify.ps1 generated vendored Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../loose-envify/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../loose-envify/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../loose-envify/cli.js" $args
} else {
& "node$exe" "$basedir/../loose-envify/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

49
board-back/node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,49 @@
{
"name": "board-back",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT",
"peer": true
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-daum-postcode": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/react-daum-postcode/-/react-daum-postcode-3.1.3.tgz",
"integrity": "sha512-qTyzUb1BeszPFO4FXSj6p83Wrn5Zpo6YqI2EZ46XSVRZT+du9CrKg9p3KshBRFKYxXmFE1Mv7wEynzXdRFNlmQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.8.0"
}
}
}
}

151
board-back/node_modules/js-tokens/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,151 @@
### Version 4.0.0 (2018-01-28) ###
- Added: Support for ES2018. The only change needed was recognizing the `s`
regex flag.
- Changed: _All_ tokens returned by the `matchToToken` function now have a
`closed` property. It is set to `undefined` for the tokens where “closed”
doesnt make sense. This means that all tokens objects have the same shape,
which might improve performance.
These are the breaking changes:
- `'/a/s'.match(jsTokens)` no longer returns `['/', 'a', '/', 's']`, but
`['/a/s']`. (There are of course other variations of this.)
- Code that rely on some token objects not having the `closed` property could
now behave differently.
### Version 3.0.2 (2017-06-28) ###
- No code changes. Just updates to the readme.
### Version 3.0.1 (2017-01-30) ###
- Fixed: ES2015 unicode escapes with more than 6 hex digits are now matched
correctly.
### Version 3.0.0 (2017-01-11) ###
This release contains one breaking change, that should [improve performance in
V8][v8-perf]:
> So how can you, as a JavaScript developer, ensure that your RegExps are fast?
> If you are not interested in hooking into RegExp internals, make sure that
> neither the RegExp instance, nor its prototype is modified in order to get the
> best performance:
>
> ```js
> var re = /./g;
> re.exec(''); // Fast path.
> re.new_property = 'slow';
> ```
This module used to export a single regex, with `.matchToToken` bolted
on, just like in the above example. This release changes the exports of
the module to avoid this issue.
Before:
```js
import jsTokens from "js-tokens"
// or:
var jsTokens = require("js-tokens")
var matchToToken = jsTokens.matchToToken
```
After:
```js
import jsTokens, {matchToToken} from "js-tokens"
// or:
var jsTokens = require("js-tokens").default
var matchToToken = require("js-tokens").matchToToken
```
[v8-perf]: http://v8project.blogspot.se/2017/01/speeding-up-v8-regular-expressions.html
### Version 2.0.0 (2016-06-19) ###
- Added: Support for ES2016. In other words, support for the `**` exponentiation
operator.
These are the breaking changes:
- `'**'.match(jsTokens)` no longer returns `['*', '*']`, but `['**']`.
- `'**='.match(jsTokens)` no longer returns `['*', '*=']`, but `['**=']`.
### Version 1.0.3 (2016-03-27) ###
- Improved: Made the regex ever so slightly smaller.
- Updated: The readme.
### Version 1.0.2 (2015-10-18) ###
- Improved: Limited npm package contents for a smaller download. Thanks to
@zertosh!
### Version 1.0.1 (2015-06-20) ###
- Fixed: Declared an undeclared variable.
### Version 1.0.0 (2015-02-26) ###
- Changed: Merged the 'operator' and 'punctuation' types into 'punctuator'. That
type is now equivalent to the Punctuator token in the ECMAScript
specification. (Backwards-incompatible change.)
- Fixed: A `-` followed by a number is now correctly matched as a punctuator
followed by a number. It used to be matched as just a number, but there is no
such thing as negative number literals. (Possibly backwards-incompatible
change.)
### Version 0.4.1 (2015-02-21) ###
- Added: Support for the regex `u` flag.
### Version 0.4.0 (2015-02-21) ###
- Improved: `jsTokens.matchToToken` performance.
- Added: Support for octal and binary number literals.
- Added: Support for template strings.
### Version 0.3.1 (2015-01-06) ###
- Fixed: Support for unicode spaces. They used to be allowed in names (which is
very confusing), and some unicode newlines were wrongly allowed in strings and
regexes.
### Version 0.3.0 (2014-12-19) ###
- Changed: The `jsTokens.names` array has been replaced with the
`jsTokens.matchToToken` function. The capturing groups of `jsTokens` are no
longer part of the public API; instead use said function. See this [gist] for
an example. (Backwards-incompatible change.)
- Changed: The empty string is now considered an “invalid” token, instead an
“empty” token (its own group). (Backwards-incompatible change.)
- Removed: component support. (Backwards-incompatible change.)
[gist]: https://gist.github.com/lydell/be49dbf80c382c473004
### Version 0.2.0 (2014-06-19) ###
- Changed: Match ES6 function arrows (`=>`) as an operator, instead of its own
category (“functionArrow”), for simplicity. (Backwards-incompatible change.)
- Added: ES6 splats (`...`) are now matched as an operator (instead of three
punctuations). (Backwards-incompatible change.)
### Version 0.1.0 (2014-03-08) ###
- Initial release.

21
board-back/node_modules/js-tokens/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014, 2015, 2016, 2017, 2018 Simon Lydell
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.

240
board-back/node_modules/js-tokens/README.md generated vendored Normal file
View File

@ -0,0 +1,240 @@
Overview [![Build Status](https://travis-ci.org/lydell/js-tokens.svg?branch=master)](https://travis-ci.org/lydell/js-tokens)
========
A regex that tokenizes JavaScript.
```js
var jsTokens = require("js-tokens").default
var jsString = "var foo=opts.foo;\n..."
jsString.match(jsTokens)
// ["var", " ", "foo", "=", "opts", ".", "foo", ";", "\n", ...]
```
Installation
============
`npm install js-tokens`
```js
import jsTokens from "js-tokens"
// or:
var jsTokens = require("js-tokens").default
```
Usage
=====
### `jsTokens` ###
A regex with the `g` flag that matches JavaScript tokens.
The regex _always_ matches, even invalid JavaScript and the empty string.
The next match is always directly after the previous.
### `var token = matchToToken(match)` ###
```js
import {matchToToken} from "js-tokens"
// or:
var matchToToken = require("js-tokens").matchToToken
```
Takes a `match` returned by `jsTokens.exec(string)`, and returns a `{type:
String, value: String}` object. The following types are available:
- string
- comment
- regex
- number
- name
- punctuator
- whitespace
- invalid
Multi-line comments and strings also have a `closed` property indicating if the
token was closed or not (see below).
Comments and strings both come in several flavors. To distinguish them, check if
the token starts with `//`, `/*`, `'`, `"` or `` ` ``.
Names are ECMAScript IdentifierNames, that is, including both identifiers and
keywords. You may use [is-keyword-js] to tell them apart.
Whitespace includes both line terminators and other whitespace.
[is-keyword-js]: https://github.com/crissdev/is-keyword-js
ECMAScript support
==================
The intention is to always support the latest ECMAScript version whose feature
set has been finalized.
If adding support for a newer version requires changes, a new version with a
major verion bump will be released.
Currently, ECMAScript 2018 is supported.
Invalid code handling
=====================
Unterminated strings are still matched as strings. JavaScript strings cannot
contain (unescaped) newlines, so unterminated strings simply end at the end of
the line. Unterminated template strings can contain unescaped newlines, though,
so they go on to the end of input.
Unterminated multi-line comments are also still matched as comments. They
simply go on to the end of the input.
Unterminated regex literals are likely matched as division and whatever is
inside the regex.
Invalid ASCII characters have their own capturing group.
Invalid non-ASCII characters are treated as names, to simplify the matching of
names (except unicode spaces which are treated as whitespace). Note: See also
the [ES2018](#es2018) section.
Regex literals may contain invalid regex syntax. They are still matched as
regex literals. They may also contain repeated regex flags, to keep the regex
simple.
Strings may contain invalid escape sequences.
Limitations
===========
Tokenizing JavaScript using regexes—in fact, _one single regex_—wont be
perfect. But thats not the point either.
You may compare jsTokens with [esprima] by using `esprima-compare.js`.
See `npm run esprima-compare`!
[esprima]: http://esprima.org/
### Template string interpolation ###
Template strings are matched as single tokens, from the starting `` ` `` to the
ending `` ` ``, including interpolations (whose tokens are not matched
individually).
Matching template string interpolations requires recursive balancing of `{` and
`}`—something that JavaScript regexes cannot do. Only one level of nesting is
supported.
### Division and regex literals collision ###
Consider this example:
```js
var g = 9.82
var number = bar / 2/g
var regex = / 2/g
```
A human can easily understand that in the `number` line were dealing with
division, and in the `regex` line were dealing with a regex literal. How come?
Because humans can look at the whole code to put the `/` characters in context.
A JavaScript regex cannot. It only sees forwards. (Well, ES2018 regexes can also
look backwards. See the [ES2018](#es2018) section).
When the `jsTokens` regex scans throught the above, it will see the following
at the end of both the `number` and `regex` rows:
```js
/ 2/g
```
It is then impossible to know if that is a regex literal, or part of an
expression dealing with division.
Here is a similar case:
```js
foo /= 2/g
foo(/= 2/g)
```
The first line divides the `foo` variable with `2/g`. The second line calls the
`foo` function with the regex literal `/= 2/g`. Again, since `jsTokens` only
sees forwards, it cannot tell the two cases apart.
There are some cases where we _can_ tell division and regex literals apart,
though.
First off, we have the simple cases where theres only one slash in the line:
```js
var foo = 2/g
foo /= 2
```
Regex literals cannot contain newlines, so the above cases are correctly
identified as division. Things are only problematic when there are more than
one non-comment slash in a single line.
Secondly, not every character is a valid regex flag.
```js
var number = bar / 2/e
```
The above example is also correctly identified as division, because `e` is not a
valid regex flag. I initially wanted to future-proof by allowing `[a-zA-Z]*`
(any letter) as flags, but it is not worth it since it increases the amount of
ambigous cases. So only the standard `g`, `m`, `i`, `y` and `u` flags are
allowed. This means that the above example will be identified as division as
long as you dont rename the `e` variable to some permutation of `gmiyus` 1 to 6
characters long.
Lastly, we can look _forward_ for information.
- If the token following what looks like a regex literal is not valid after a
regex literal, but is valid in a division expression, then the regex literal
is treated as division instead. For example, a flagless regex cannot be
followed by a string, number or name, but all of those three can be the
denominator of a division.
- Generally, if what looks like a regex literal is followed by an operator, the
regex literal is treated as division instead. This is because regexes are
seldomly used with operators (such as `+`, `*`, `&&` and `==`), but division
could likely be part of such an expression.
Please consult the regex source and the test cases for precise information on
when regex or division is matched (should you need to know). In short, you
could sum it up as:
If the end of a statement looks like a regex literal (even if it isnt), it
will be treated as one. Otherwise it should work as expected (if you write sane
code).
### ES2018 ###
ES2018 added some nice regex improvements to the language.
- [Unicode property escapes] should allow telling names and invalid non-ASCII
characters apart without blowing up the regex size.
- [Lookbehind assertions] should allow matching telling division and regex
literals apart in more cases.
- [Named capture groups] might simplify some things.
These things would be nice to do, but are not critical. They probably have to
wait until the oldest maintained Node.js LTS release supports those features.
[Unicode property escapes]: http://2ality.com/2017/07/regexp-unicode-property-escapes.html
[Lookbehind assertions]: http://2ality.com/2017/05/regexp-lookbehind-assertions.html
[Named capture groups]: http://2ality.com/2017/05/regexp-named-capture-groups.html
License
=======
[MIT](LICENSE).

23
board-back/node_modules/js-tokens/index.js generated vendored Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell
// License: MIT. (See LICENSE.)
Object.defineProperty(exports, "__esModule", {
value: true
})
// This regex comes from regex.coffee, and is inserted here by generate-index.js
// (run `npm run build`).
exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g
exports.matchToToken = function(match) {
var token = {type: "invalid", value: match[0], closed: undefined}
if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4])
else if (match[ 5]) token.type = "comment"
else if (match[ 6]) token.type = "comment", token.closed = !!match[7]
else if (match[ 8]) token.type = "regex"
else if (match[ 9]) token.type = "number"
else if (match[10]) token.type = "name"
else if (match[11]) token.type = "punctuator"
else if (match[12]) token.type = "whitespace"
return token
}

312
board-back/node_modules/js-tokens/package-lock.json generated vendored Normal file
View File

@ -0,0 +1,312 @@
{
"name": "js-tokens",
"version": "4.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "js-tokens",
"version": "4.0.0",
"license": "MIT",
"dependencies": {
"js-tokens": "file:"
},
"devDependencies": {
"coffeescript": "2.1.1",
"esprima": "4.0.0",
"everything.js": "1.0.3",
"mocha": "5.0.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/browser-stdout": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
"integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==",
"dev": true,
"license": "ISC"
},
"node_modules/coffeescript": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.1.1.tgz",
"integrity": "sha512-Tl2z6/rNMqJ2LqWlVxLKwLF9FniwJpweonfSLCwhX8NFCEsGBcFIErtfKd8+t4XHDSYRshj9FXxPX53BT3lC9w==",
"dev": true,
"license": "MIT",
"bin": {
"cake": "bin/cake",
"coffee": "bin/coffee"
},
"engines": {
"node": ">=6"
}
},
"node_modules/commander": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
"dev": true,
"license": "MIT"
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/diff": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/esprima": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/everything.js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/everything.js/-/everything.js-1.0.3.tgz",
"integrity": "sha512-q3gJDpTS5VUyMToQ8j9F0O0mgdU1uMKihbcOkF2mbybSHNVtPRhSzXrqgH2tQ+Clca40MsoWYtUndeBr14BQaw==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
}
},
"node_modules/growl": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
"integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4.x"
}
},
"node_modules/has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
"integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==",
"dev": true,
"license": "MIT",
"bin": {
"he": "bin/he"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
"license": "ISC"
},
"node_modules/js-tokens": {
"resolved": "",
"link": true
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==",
"dev": true,
"license": "MIT"
},
"node_modules/mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==",
"deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "0.0.8"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/mocha": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz",
"integrity": "sha512-ukB2dF+u4aeJjc6IGtPNnJXfeby5d4ZqySlIBT0OEyva/DrMjVm5HkQxKnHDLKEfEQBsEnwTg9HHhtPHJdTd8w==",
"dev": true,
"license": "MIT",
"dependencies": {
"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"
},
"bin": {
"_mocha": "bin/_mocha",
"mocha": "bin/mocha"
},
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true,
"license": "MIT"
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/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==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^2.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
}
}
}

33
board-back/node_modules/js-tokens/package.json generated vendored Normal file
View File

@ -0,0 +1,33 @@
{
"name": "js-tokens",
"version": "4.0.0",
"author": "Simon Lydell",
"license": "MIT",
"description": "A regex that tokenizes JavaScript.",
"keywords": [
"JavaScript",
"js",
"token",
"tokenize",
"regex"
],
"files": [
"index.js"
],
"repository": "lydell/js-tokens",
"scripts": {
"test": "mocha --ui tdd",
"esprima-compare": "node esprima-compare ./index.js everything.js/es5.js",
"build": "node generate-index.js",
"dev": "npm run build && npm test"
},
"devDependencies": {
"coffeescript": "2.1.1",
"esprima": "4.0.0",
"everything.js": "1.0.3",
"mocha": "5.0.0"
},
"dependencies": {
"js-tokens": "file:"
}
}

21
board-back/node_modules/loose-envify/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Andres Suarez <zertosh@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.

45
board-back/node_modules/loose-envify/README.md generated vendored Normal file
View File

@ -0,0 +1,45 @@
# loose-envify
[![Build Status](https://travis-ci.org/zertosh/loose-envify.svg?branch=master)](https://travis-ci.org/zertosh/loose-envify)
Fast (and loose) selective `process.env` replacer using [js-tokens](https://github.com/lydell/js-tokens) instead of an AST. Works just like [envify](https://github.com/hughsk/envify) but much faster.
## Gotchas
* Doesn't handle broken syntax.
* Doesn't look inside embedded expressions in template strings.
- **this won't work:**
```js
console.log(`the current env is ${process.env.NODE_ENV}`);
```
* Doesn't replace oddly-spaced or oddly-commented expressions.
- **this won't work:**
```js
console.log(process./*won't*/env./*work*/NODE_ENV);
```
## Usage/Options
loose-envify has the exact same interface as [envify](https://github.com/hughsk/envify), including the CLI.
## Benchmark
```
envify:
$ for i in {1..5}; do node bench/bench.js 'envify'; done
708ms
727ms
791ms
719ms
720ms
loose-envify:
$ for i in {1..5}; do node bench/bench.js '../'; done
51ms
52ms
52ms
52ms
52ms
```

16
board-back/node_modules/loose-envify/cli.js generated vendored Normal file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env node
'use strict';
var looseEnvify = require('./');
var fs = require('fs');
if (process.argv[2]) {
fs.createReadStream(process.argv[2], {encoding: 'utf8'})
.pipe(looseEnvify(process.argv[2]))
.pipe(process.stdout);
} else {
process.stdin.resume()
process.stdin
.pipe(looseEnvify(__filename))
.pipe(process.stdout);
}

4
board-back/node_modules/loose-envify/custom.js generated vendored Normal file
View File

@ -0,0 +1,4 @@
// envify compatibility
'use strict';
module.exports = require('./loose-envify');

3
board-back/node_modules/loose-envify/index.js generated vendored Normal file
View File

@ -0,0 +1,3 @@
'use strict';
module.exports = require('./loose-envify')(process.env);

36
board-back/node_modules/loose-envify/loose-envify.js generated vendored Normal file
View File

@ -0,0 +1,36 @@
'use strict';
var stream = require('stream');
var util = require('util');
var replace = require('./replace');
var jsonExtRe = /\.json$/;
module.exports = function(rootEnv) {
rootEnv = rootEnv || process.env;
return function (file, trOpts) {
if (jsonExtRe.test(file)) {
return stream.PassThrough();
}
var envs = trOpts ? [rootEnv, trOpts] : [rootEnv];
return new LooseEnvify(envs);
};
};
function LooseEnvify(envs) {
stream.Transform.call(this);
this._data = '';
this._envs = envs;
}
util.inherits(LooseEnvify, stream.Transform);
LooseEnvify.prototype._transform = function(buf, enc, cb) {
this._data += buf;
cb();
};
LooseEnvify.prototype._flush = function(cb) {
var replaced = replace(this._data, this._envs);
this.push(replaced);
cb();
};

5195
board-back/node_modules/loose-envify/package-lock.json generated vendored Normal file

File diff suppressed because it is too large Load Diff

37
board-back/node_modules/loose-envify/package.json generated vendored Normal file
View File

@ -0,0 +1,37 @@
{
"name": "loose-envify",
"version": "1.4.0",
"description": "Fast (and loose) selective `process.env` replacer using js-tokens instead of an AST",
"keywords": [
"environment",
"variables",
"browserify",
"browserify-transform",
"transform",
"source",
"configuration"
],
"homepage": "https://github.com/zertosh/loose-envify",
"license": "MIT",
"author": "Andres Suarez <zertosh@gmail.com>",
"main": "index.js",
"bin": {
"loose-envify": "cli.js"
},
"repository": {
"type": "git",
"url": "git://github.com/zertosh/loose-envify.git"
},
"scripts": {
"test": "tap test/*.js"
},
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0",
"loose-envify": "file:"
},
"devDependencies": {
"browserify": "^13.1.1",
"envify": "^3.4.0",
"tap": "^8.0.0"
}
}

65
board-back/node_modules/loose-envify/replace.js generated vendored Normal file
View File

@ -0,0 +1,65 @@
'use strict';
var jsTokens = require('js-tokens').default;
var processEnvRe = /\bprocess\.env\.[_$a-zA-Z][$\w]+\b/;
var spaceOrCommentRe = /^(?:\s|\/[/*])/;
function replace(src, envs) {
if (!processEnvRe.test(src)) {
return src;
}
var out = [];
var purge = envs.some(function(env) {
return env._ && env._.indexOf('purge') !== -1;
});
jsTokens.lastIndex = 0
var parts = src.match(jsTokens);
for (var i = 0; i < parts.length; i++) {
if (parts[i ] === 'process' &&
parts[i + 1] === '.' &&
parts[i + 2] === 'env' &&
parts[i + 3] === '.') {
var prevCodeToken = getAdjacentCodeToken(-1, parts, i);
var nextCodeToken = getAdjacentCodeToken(1, parts, i + 4);
var replacement = getReplacementString(envs, parts[i + 4], purge);
if (prevCodeToken !== '.' &&
nextCodeToken !== '.' &&
nextCodeToken !== '=' &&
typeof replacement === 'string') {
out.push(replacement);
i += 4;
continue;
}
}
out.push(parts[i]);
}
return out.join('');
}
function getAdjacentCodeToken(dir, parts, i) {
while (true) {
var part = parts[i += dir];
if (!spaceOrCommentRe.test(part)) {
return part;
}
}
}
function getReplacementString(envs, name, purge) {
for (var j = 0; j < envs.length; j++) {
var env = envs[j];
if (typeof env[name] !== 'undefined') {
return JSON.stringify(env[name]);
}
}
if (purge) {
return 'undefined';
}
}
module.exports = replace;

View File

@ -0,0 +1,69 @@
### > 1.8.3
[Github 레포지터리의 릴리즈 기록을 참고해주세요](https://github.com/bernard-kms/react-daum-postcode/releases)
### 1.8.2
- 검색결과 TypeScript 타입에 `noSelected` 인자 추
### 1.8.1
- TypeScript 타입선언 업데이트
### 1.8.0
- 구 우편번호를 검색 결과에서 제외하는 `zonecodeOnly` props 추가
### 1.7.1
- Daum Postcode 커스텀 props가 DOM으로 주입되는 문제 해결
### 1.7.0
- React 버전을 16.4로 올림
- TypeScript 타입선언 파일을 추가
- `DaumPostcode`컴포넌트 타입
- 컴포넌트의 props인 `DaumPostcodeProps` 타입
- _onComplete_ props의 인자로 쓰이는 `AddressData` 타입
### 1.6.0
- React 버전을 16.3 으로 올림
- `alwaysShowEngAddr`, `submitMode`, `useSuggest` 생성자 속성을 추가
### 1.5.0
- Daum 우편번호 스크립트가 로드되지 않을때, 오류 메시지를 표시
- 패키지 라이브러리를 빌드할 때 minify 적용
### 1.4.2
- 다음 우편주소 검색창이 여러번 반복해서 열릴수 있도록 함
### 1.4.1
- 다음 우편주소 스크립트를 중복으로 생성하지 않도록 함 ([@ignocide](https://github.com/ignocide) in [#3](https://github.com/kimminsik-bernard/react-daum-postcode/pull/3))
- React 버전을 16.2.0으로 올림
### 1.4.0
- 다음 우편번호 생성자가 받을수 있는 모든 속성을 props를 통해 전달
- React 버전을 16.0.0으로 올림
### 1.3.0
- 다음 우편번호 스크립트를 자체적으로 로드
- README 수정
### 1.2.1
- 에러 핸들링 개선
- README 수정
### 1.2.0
- React 버전을 15.5.0으로 올림
- prop-types 패키지 사용
### 1.1.0
- 다음 우편번호 스크립트를 동적으로 로딩
### 1.0.1
- 문서 수정
- eslint 설정
### 1.0.0
- 최초 배포

128
board-back/node_modules/react-daum-postcode/README.md generated vendored Normal file
View File

@ -0,0 +1,128 @@
# react-daum-postcode
Daum 우편번호 검색 서비스를 React 환경에서 간편하게 이용할 수 있습니다.
## Install
```bash
npm install react-daum-postcode
# or
yarn add react-daum-postcode
# if react not installed, install react also.
npm install react
# or
yarn add react
```
## Embed
`DaumPostcodeEmbed` 컴포넌트를 사용하여, 우편번호 검색 서비스를 임베드 방식으로 사용할 수 있습니다.
```javascript
import React from 'react';
import DaumPostcodeEmbed from 'react-daum-postcode';
const Postcode = () => {
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = '';
if (data.addressType === 'R') {
if (data.bname !== '') {
extraAddress += data.bname;
}
if (data.buildingName !== '') {
extraAddress += extraAddress !== '' ? `, ${data.buildingName}` : data.buildingName;
}
fullAddress += extraAddress !== '' ? ` (${extraAddress})` : '';
}
console.log(fullAddress); // e.g. '서울 성동구 왕십리로2길 20 (성수동1가)'
};
return <DaumPostcodeEmbed onComplete={handleComplete} {...props} />;
};
```
`DaumPostcodeEmbed` 컴포넌트에 다음 우편번호 서비스의 생성자 및 임베드 설정값 등을 `props`로 전달할 수 있습니다. 전달하지 않은 설정값은 다음 우편번호 서비스의 기본 설정을 따라갑니다.
| name | type | default | description
|:----:|:----:|:-------:|:-----------|
| scriptUrl | `string` | [CURRENT_URL](https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js) | Daum 우편번호 서비스의 스크립트 주소입니다.|
| onComplete | `function` | `undefined` | 우편번호 검색이 끝났을 때 사용자가 선택한 정보를 받아올 콜백함수입니다. 주소 데이터의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| onSearch | `function` | `undefined` | 주소를 검색할 경우 실행되는 콜백함수입니다. 검색 결과 정보의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| onClose | `function` | `undefined` | 검색 결과를 선택하여, 서비스가 닫힐 때 실행되는 콜백함수입니다. |
| onResize | `function` | `undefined` | 검색 결과로 인해, 우편번호 서비스의 화면 크기가 변경될 때 호출되는 콜백함수입니다. 변경된 화면 정보의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| className | `string` | `undefined` | 우편번호 검색창을 감싸는 최상위 엘리먼트에 적용할 클래스 이름입니다. |
| style | `object` | `{ width:"100%", height:400 }` | 우편번호 검색창을 감싸는 최상위 엘리먼트에 적용할 스타일입니다. |
| defaultQuery | `string` | `undefined` | 우편번호 검색창에 기본으로 입력할 검색어입니다.
| autoClose | `boolean` | `true` | 우편번호 검색 완료시 자동 닫힘 여부입니다. 주소를 선택하면, 최상위 엘리먼트를 돔에서 제거합니다. |
| errorMessage | `ReactNode` | `<p>현재 Daum 우편번호 서비스를 이용할 수 없습니다. 잠시 후 다시 시도해주세요.</p>` | 우편번호 서비스 스크립트 로드에 실패했을 때 나타낼 에러 메세지 입니다. |
기타 Daum 우편번호 생성자 속성들을 동일한 이름으로 props를 전달할 수 있습니다. 속성값에 대해서는 [Daum 우편번호 서비스 가이드](http://postcode.map.daum.net/guide#attributes)를 참고해주세요.
## Popup
`useDaumPostcodePopup` hook 을 사용하여, 반환받은 함수를 통해 우편번호 검색 서비스를 팝업 방식으로 이용할 수 있습니다.
```javascript
import React from 'react';
import { useDaumPostcodePopup } from 'react-daum-postcode';
const Postcode = () => {
const open = useDaumPostcodePopup(scriptUrl);
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = '';
if (data.addressType === 'R') {
if (data.bname !== '') {
extraAddress += data.bname;
}
if (data.buildingName !== '') {
extraAddress += extraAddress !== '' ? `, ${data.buildingName}` : data.buildingName;
}
fullAddress += extraAddress !== '' ? ` (${extraAddress})` : '';
}
console.log(fullAddress); // e.g. '서울 성동구 왕십리로2길 20 (성수동1가)'
};
const handleClick = () => {
open({ onComplete: handleComplete });
};
return (
<button type='button' onClick={handleClick}>
Open
</button>
);
};
```
`useDaumPostcodePopup` 실행 시 우편번호 서비스의 스크립트 주소를 전달할 수 있습니다. 반환한 함수를 실행할 때 다음 우편번호 서비스의 생성자 및 팝업 설정값을 전달할 수 있습니다. 전달하지 않은 설정값은 다음 우편번호 서비스의 기본 설정을 따라갑니다.
| name | type | default | description
|:----:|:----:|:-------:|:-----------|
| scriptUrl | `string` | [CURRENT_URL](https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js) | Daum 우편번호 서비스의 스크립트 주소입니다.|
| onComplete | `function` | `undefined` | 우편번호 검색이 끝났을 때 사용자가 선택한 정보를 받아올 콜백함수입니다. 주소 데이터의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| onSearch | `function` | `undefined` | 주소를 검색할 경우 실행되는 콜백함수입니다. 검색 결과 정보의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| onClose | `function` | `undefined` | 검색 결과를 선택하여, 서비스가 닫힐 때 실행되는 콜백함수입니다. |
| onResize | `function` | `undefined` | 검색 결과로 인해, 우편번호 서비스의 화면 크기가 변경될 때 호출되는 콜백함수입니다. 변경된 화면 정보의 구성은 [Daum 가이드](http://postcode.map.daum.net/guide)를 참고해주세요. |
| width | `string\|number` | `undefined` | 우편번호 검색창의 가로 너비입니다. |
| height | `string\|number` | `undefined` | 우편번호 검색창의 세로 높이입니다. |
| defaultQuery | `string` | `undefined` | 우편번호 검색창에 기본으로 입력할 검색어입니다. |
| top | `string\|number` | `undefined` | 팝업의 Y 위치를 나타내는 값입니다. |
| left | `string\|number` | `undefined` | 팝업의 X 위치를 나타내는 값입니다. |
| popupTitle | `string` | `undefined` | 팝업창의 상태표시줄에 나오는 Title 값을 지정할 수 있습니다. 전달하지 않을 경우, 다음 우편번호의 기본 설정 문구가 출력됩니다. |
| popupKey | `string` | `undefined` | 팝업창의 key 입니다. 전달하지 않을 경우 매번 새창이 열리게 됩니다. |
| autoClose | `boolean` | `true` | 우편번호 검색 완료시 자동 닫힘 여부입니다. 주소를 선택하면 팝업창이 닫힙니다.
기타 Daum 우편번호 생성자 속성들을 동일한 이름으로 props를 전달할 수 있습니다. 속성값에 대해서는 [Daum 우편번호 서비스 가이드](http://postcode.map.daum.net/guide#attributes)를 참고해주세요.
## 안내
`react-daum-postcode`는 Daum 우편번호 서비스와 독립적으로 제작된 패키지입니다. React환경에서 발생하는 `react-daum-postcode`의 버그는 패키지 레포지터리의 [이슈트래커](https://github.com/kimminsik-bernard/react-daum-postcode/issues)에 말씀해주세요. 만약 Daum 우편번호 서비스 자체의 문제라고 생각하신다면, 다음 우편번호 서비스의 [FAQ](https://github.com/daumPostcode/QnA/blob/master/README.md)와 [이슈트래커](https://github.com/daumPostcode/QnA/issues)를 참조해주세요.

View File

@ -0,0 +1,44 @@
import React, { Component, CSSProperties } from 'react';
import { PostcodeConstructor, PostcodeOptions } from './loadPostcode';
export interface DaumPostcodeEmbedProps extends Omit<PostcodeOptions, 'oncomplete' | 'onresize' | 'onclose' | 'onsearch' | 'width' | 'height'> {
onComplete?: PostcodeOptions['oncomplete'];
onResize?: PostcodeOptions['onresize'];
onClose?: PostcodeOptions['onclose'];
onSearch?: PostcodeOptions['onsearch'];
className?: string;
style?: CSSProperties;
defaultQuery?: string;
errorMessage?: string | React.ReactNode;
scriptUrl?: string;
autoClose?: boolean;
}
/**
* @deprecated
* type 'DaumPostcodeProps' is renamed to 'DaumPostcodeEmbedProps'.
* use 'DaumPostcodeEmbedProps' instead of 'DaumPostcodeProps'.
* it will be removed future version.
*/
export declare type DaumPostcodeProps = DaumPostcodeEmbedProps;
interface State {
hasError: boolean;
}
declare class DaumPostcodeEmbed extends Component<DaumPostcodeEmbedProps, State> {
static defaultProps: {
scriptUrl: string;
errorMessage: JSX.Element;
autoClose: boolean;
};
/**
* See #61
*/
private mounted;
wrap: React.RefObject<HTMLDivElement>;
state: {
hasError: boolean;
};
componentDidMount(): void;
initiate: (Postcode: PostcodeConstructor) => void;
onError: (e: unknown) => void;
render(): JSX.Element;
}
export default DaumPostcodeEmbed;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
import DaumPostcodeEmbed, { DaumPostcodeEmbedProps, DaumPostcodeProps } from './DaumPostcodeEmbed';
import useDaumPostcodePopup, { DaumPostcodePopupParams } from './useDaumPostcodePopup';
import loadPostcode, { Address, Search, State } from './loadPostcode';
export type { DaumPostcodeEmbedProps, DaumPostcodeProps, DaumPostcodePopupParams, Address, Search, State };
export { loadPostcode, DaumPostcodeEmbed, useDaumPostcodePopup };
export default DaumPostcodeEmbed;

View File

@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"DaumPostcodeEmbed",{enumerable:!0,get:function get(){return _DaumPostcodeEmbed.default}}),Object.defineProperty(exports,"useDaumPostcodePopup",{enumerable:!0,get:function get(){return _useDaumPostcodePopup.default}}),Object.defineProperty(exports,"loadPostcode",{enumerable:!0,get:function get(){return _loadPostcode.default}}),exports.default=void 0;var _DaumPostcodeEmbed=_interopRequireDefault(require("./DaumPostcodeEmbed")),_useDaumPostcodePopup=_interopRequireDefault(require("./useDaumPostcodePopup")),_loadPostcode=_interopRequireDefault(require("./loadPostcode"));function _interopRequireDefault(a){return a&&a.__esModule?a:{default:a}}var _default=_DaumPostcodeEmbed.default;exports.default=_default;

View File

@ -0,0 +1,117 @@
declare global {
interface Window {
daum?: {
postcode: {
load: (fn: () => void) => void;
version: string;
_validParam_: boolean;
};
Postcode: PostcodeConstructor;
};
}
}
export interface Address {
zonecode: string;
address: string;
addressEnglish: string;
addressType: 'R' | 'J';
userSelectedType: 'R' | 'J';
noSelected: 'Y' | 'N';
userLanguageType: 'K' | 'E';
roadAddress: string;
roadAddressEnglish: string;
jibunAddress: string;
jibunAddressEnglish: string;
autoRoadAddress: string;
autoRoadAddressEnglish: string;
autoJibunAddress: string;
autoJibunAddressEnglish: string;
buildingCode: string;
buildingName: string;
apartment: 'Y' | 'N';
sido: string;
sidoEnglish: string;
sigungu: string;
sigunguEnglish: string;
sigunguCode: string;
roadnameCode: string;
bcode: string;
roadname: string;
roadnameEnglish: string;
bname: string;
bnameEnglish: string;
bname1: string;
bname1English: string;
bname2: string;
bname2English: string;
hname: string;
query: string;
}
export interface Size {
width: number;
height: number;
}
export declare type State = 'FORCE_CLOSE' | 'COMPLETE_CLOSE';
export interface Search {
q: string;
count: number;
}
export interface Theme {
bgColor?: string;
searchBgColor?: string;
contentBgColor?: string;
pageBgColor?: string;
textColor?: string;
queryTextColor?: string;
postcodeTextColor?: string;
emphTextColor?: string;
outlineColor?: string;
}
export interface PostcodeOptions {
oncomplete?: (address: Address) => void;
onresize?: (size: Size) => void;
onclose?: (state: State) => void;
onsearch?: (search: Search) => void;
width?: string | number;
height?: string | number;
animation?: boolean;
focusInput?: boolean;
focusContent?: boolean;
autoMapping?: boolean;
autoMappingRoad?: boolean;
autoMappingJibun?: boolean;
shorthand?: boolean;
pleaseReadGuide?: number;
pleaseReadGuideTimer?: number;
maxSuggestItems?: number;
showMoreHName?: boolean;
hideMapBtn?: boolean;
hideEngBtn?: boolean;
alwaysShowEngAddr?: boolean;
submitMode?: boolean;
useBannerLink?: boolean;
theme?: Theme;
useSuggest?: boolean;
}
export interface OpenOptions {
q?: string;
left?: number | string;
top?: number | string;
popupTitle?: string;
popupKey?: string;
autoClose?: boolean;
}
export interface EmbedOptions {
q?: string;
autoClose?: boolean;
}
export interface PostcodeConstructor {
new (postcodeOptions: PostcodeOptions): Postcode;
}
export interface Postcode {
open(openOptions?: OpenOptions): void;
embed(element: HTMLElement, embedOptions?: EmbedOptions): void;
}
export declare const postcodeScriptUrl = "https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js";
declare const loadPostcode: (url?: string) => Promise<PostcodeConstructor>;
export default loadPostcode;

View File

@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.postcodeScriptUrl=void 0;var postcodeScriptUrl="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js";exports.postcodeScriptUrl="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js";var loadPostcode=function(){var a=null;return function(){var b=0<arguments.length&&void 0!==arguments[0]?arguments[0]:postcodeScriptUrl;return a?a:(a=new Promise(function(a,c){var d=document.createElement("script");d.src=b,d.onload=function(){var b,d;return null!==(b=window)&&void 0!==b&&null!==(d=b.daum)&&void 0!==d&&d.Postcode?a(window.daum.Postcode):void c(new Error("Script is loaded successfully, but cannot find Postcode module. Check your scriptURL property."))},d.onerror=function(a){return c(a)},d.id="daum_postcode_script",document.body.appendChild(d)}),a)}}(),_default=loadPostcode;exports.default=_default;

View File

@ -0,0 +1,11 @@
import { PostcodeOptions, OpenOptions } from './loadPostcode';
export declare type DaumPostcodePopupParams = Omit<PostcodeOptions, 'oncomplete' | 'onresize' | 'onclose' | 'onsearch'> & Omit<OpenOptions, 'q'> & {
onComplete?: PostcodeOptions['oncomplete'];
onResize?: PostcodeOptions['onresize'];
onClose?: PostcodeOptions['onclose'];
onSearch?: PostcodeOptions['onsearch'];
onError?: (error: Error) => void;
defaultQuery?: string;
};
declare function useDaumPostcodePopup(scriptUrl?: string): (options?: DaumPostcodePopupParams | undefined) => Promise<void>;
export default useDaumPostcodePopup;

View File

@ -0,0 +1 @@
"use strict";function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _react=require("react"),_loadPostcode=_interopRequireWildcard(require("./loadPostcode")),_excluded=["defaultQuery","left","top","popupKey","popupTitle","autoClose","onComplete","onResize","onClose","onSearch","onError"];function _getRequireWildcardCache(a){if("function"!=typeof WeakMap)return null;var b=new WeakMap,c=new WeakMap;return(_getRequireWildcardCache=function(a){return a?c:b})(a)}function _interopRequireWildcard(a,b){if(!b&&a&&a.__esModule)return a;if(null===a||"object"!==_typeof(a)&&"function"!=typeof a)return{default:a};var c=_getRequireWildcardCache(b);if(c&&c.has(a))return c.get(a);var d={},e=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a)if("default"!=f&&Object.prototype.hasOwnProperty.call(a,f)){var g=e?Object.getOwnPropertyDescriptor(a,f):null;g&&(g.get||g.set)?Object.defineProperty(d,f,g):d[f]=a[f]}return d.default=a,c&&c.set(a,d),d}function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _defineProperty(a,b,c){return b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],0<=b.indexOf(c)||Object.prototype.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c,d,e={},f=Object.keys(a);for(d=0;d<f.length;d++)c=f[d],0<=b.indexOf(c)||(e[c]=a[c]);return e}function useDaumPostcodePopup(){var a=0<arguments.length&&arguments[0]!==void 0?arguments[0]:_loadPostcode.postcodeScriptUrl;(0,_react.useEffect)(function(){(0,_loadPostcode.default)(a)},[a]);var b=(0,_react.useCallback)(function(b){var c=_objectSpread({},b),d=c.defaultQuery,e=c.left,f=c.top,g=c.popupKey,h=c.popupTitle,i=c.autoClose,j=c.onComplete,k=c.onResize,l=c.onClose,m=c.onSearch,n=c.onError,o=_objectWithoutProperties(c,_excluded);return(0,_loadPostcode.default)(a).then(function(a){var b=new a(_objectSpread(_objectSpread({},o),{},{oncomplete:j,onsearch:m,onresize:k,onclose:l}));b.open({q:d,left:e,top:f,popupTitle:h,popupKey:g,autoClose:i})}).catch(n)},[a]);return b}var _default=useDaumPostcodePopup;exports.default=_default;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
{
"name": "react-daum-postcode",
"version": "3.1.3",
"description": "Daum Postcode service for React",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"files": [
"lib"
],
"scripts": {
"build": "concurrently \"yarn:build:*\"",
"build:babel": "babel src -d lib --extensions \".ts,.tsx\"",
"build:types": "tsc --declarationDir lib"
},
"author": "kimminsik-bernard",
"contributors": [
{
"name": "Minsik Kim",
"url": "https://github.com/kimminsik-bernard"
},
{
"name": "Sungmin Kim",
"url": "https://github.com/ignocide"
},
{
"name": "jong-hui",
"url": "https://github.com/jong-hui"
},
{
"name": "KimSeonghyeon",
"url": "https://github.com/seonghyeonkimm"
},
{
"name": "Jieun Lee",
"url": "https://github.com/ee2e"
},
{
"name": "Chalk",
"url": "https://github.com/ChalkPE"
},
{
"name": "Normaltic",
"url": "https://github.com/Normaltic"
},
{
"name": "TaeSang Cho",
"url": "https://github.com/Web-Engine"
},
{
"name": "HK1211",
"url": "https://github.com/HK1211"
}
],
"repository": {
"type": "git",
"url": "git+https://github.com/kimminsik-bernard/react-daum-postcode.git"
},
"keywords": [
"react",
"daum",
"postcode",
"zipcode"
],
"license": "MIT",
"peerDependencies": {
"react": ">=16.8.0"
},
"devDependencies": {
"@babel/cli": "^7.14.8",
"@babel/core": "^7.14.8",
"@babel/eslint-parser": "^7.14.9",
"@babel/eslint-plugin": "^7.14.5",
"@babel/preset-env": "^7.14.9",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
"@types/react": "^17.0.15",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"babel-preset-minify": "^0.5.1",
"concurrently": "^6.2.0",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"typescript": "^4.3.5"
},
"dependencies": {
"react-daum-postcode": "file:"
}
}

21
board-back/node_modules/react/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
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.

37
board-back/node_modules/react/README.md generated vendored Normal file
View File

@ -0,0 +1,37 @@
# `react`
React is a JavaScript library for creating user interfaces.
The `react` package contains only the functionality necessary to define React components. It is typically used together with a React renderer like `react-dom` for the web, or `react-native` for the native environments.
**Note:** by default, React will be in development mode. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages. Don't forget to use the [production build](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build) when deploying your application.
## Usage
```js
import { useState } from 'react';
import { createRoot } from 'react-dom/client';
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</>
);
}
const root = createRoot(document.getElementById('root'));
root.render(<App />);
```
## Documentation
See https://reactjs.org/
## API
See https://reactjs.org/docs/react-api.html

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
/**
* @license React
* react-jsx-dev-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';var a=Symbol.for("react.fragment");exports.Fragment=a;exports.jsxDEV=void 0;

View File

@ -0,0 +1,10 @@
/**
* @license React
* react-jsx-dev-runtime.profiling.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';var a=Symbol.for("react.fragment");exports.Fragment=a;exports.jsxDEV=void 0;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';var f=require("react"),k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};
function q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=""+g);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q;

View File

@ -0,0 +1,11 @@
/**
* @license React
* react-jsx-runtime.profiling.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';var f=require("react"),k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};
function q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=""+g);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q;

2740
board-back/node_modules/react/cjs/react.development.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';var l=Symbol.for("react.element"),n=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),u=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),z=Symbol.iterator;function A(a){if(null===a||"object"!==typeof a)return null;a=z&&a[z]||a["@@iterator"];return"function"===typeof a?a:null}
var B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};
E.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;
H.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};
function M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}
function N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return"object"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\/+/g;function Q(a,b){return"object"===typeof a&&null!==a&&null!=a.key?escape(""+a.key):b.toString(36)}
function R(a,b,e,d,c){var k=typeof a;if("undefined"===k||"boolean"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=""===d?"."+Q(h,0):d,I(c)?(e="",null!=a&&(e=a.replace(P,"$&/")+"/"),R(c,b,e,"",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?"":(""+c.key).replace(P,"$&/")+"/")+a)),b.push(c)),1;h=0;d=""===d?".":d+":";if(I(a))for(var g=0;g<a.length;g++){k=
a[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),"function"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if("object"===k)throw b=String(a),Error("Objects are not valid as a React child (found: "+("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}
function S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,"","",function(a){return b.call(e,a,c++)});return d}function T(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}
var U={current:null},V={transition:null},W={ReactCurrentDispatcher:U,ReactCurrentBatchConfig:V,ReactCurrentOwner:K};function X(){throw Error("act(...) is not supported in production builds of React.");}
exports.Children={map:S,forEach:function(a,b,e){S(a,function(){b.apply(this,arguments)},e)},count:function(a){var b=0;S(a,function(){b++});return b},toArray:function(a){return S(a,function(a){return a})||[]},only:function(a){if(!O(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};exports.Component=E;exports.Fragment=p;exports.Profiler=r;exports.PureComponent=G;exports.StrictMode=q;exports.Suspense=w;
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=W;exports.act=X;
exports.cloneElement=function(a,b,e){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var d=C({},a.props),c=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=K.current);void 0!==b.key&&(c=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)J.call(b,f)&&!L.hasOwnProperty(f)&&(d[f]=void 0===b[f]&&void 0!==g?g[f]:b[f])}var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){g=Array(f);
for(var m=0;m<f;m++)g[m]=arguments[m+2];d.children=g}return{$$typeof:l,type:a.type,key:c,ref:k,props:d,_owner:h}};exports.createContext=function(a){a={$$typeof:u,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:t,_context:a};return a.Consumer=a};exports.createElement=M;exports.createFactory=function(a){var b=M.bind(null,a);b.type=a;return b};exports.createRef=function(){return{current:null}};
exports.forwardRef=function(a){return{$$typeof:v,render:a}};exports.isValidElement=O;exports.lazy=function(a){return{$$typeof:y,_payload:{_status:-1,_result:a},_init:T}};exports.memo=function(a,b){return{$$typeof:x,type:a,compare:void 0===b?null:b}};exports.startTransition=function(a){var b=V.transition;V.transition={};try{a()}finally{V.transition=b}};exports.unstable_act=X;exports.useCallback=function(a,b){return U.current.useCallback(a,b)};exports.useContext=function(a){return U.current.useContext(a)};
exports.useDebugValue=function(){};exports.useDeferredValue=function(a){return U.current.useDeferredValue(a)};exports.useEffect=function(a,b){return U.current.useEffect(a,b)};exports.useId=function(){return U.current.useId()};exports.useImperativeHandle=function(a,b,e){return U.current.useImperativeHandle(a,b,e)};exports.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};exports.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};
exports.useMemo=function(a,b){return U.current.useMemo(a,b)};exports.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};exports.useRef=function(a){return U.current.useRef(a)};exports.useState=function(a){return U.current.useState(a)};exports.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)};exports.useTransition=function(){return U.current.useTransition()};exports.version="18.3.1";

View File

@ -0,0 +1,20 @@
/**
* @license React
* react.shared-subset.development.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
if (process.env.NODE_ENV !== "production") {
(function() {
'use strict';
// eslint-disable-next-line react-internal/prod-error-codes
throw new Error('This entry point is not yet supported outside of experimental channels');
})();
}

View File

@ -0,0 +1,10 @@
/**
* @license React
* react.shared-subset.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';throw Error("This entry point is not yet supported outside of experimental channels");

7
board-back/node_modules/react/index.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react.production.min.js');
} else {
module.exports = require('./cjs/react.development.js');
}

7
board-back/node_modules/react/jsx-dev-runtime.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
} else {
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
}

7
board-back/node_modules/react/jsx-runtime.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
} else {
module.exports = require('./cjs/react-jsx-runtime.development.js');
}

42
board-back/node_modules/react/package-lock.json generated vendored Normal file
View File

@ -0,0 +1,42 @@
{
"name": "react",
"version": "18.3.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "react",
"version": "18.3.1",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"react": "file:"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/react": {
"resolved": "",
"link": true
}
}
}

48
board-back/node_modules/react/package.json generated vendored Normal file
View File

@ -0,0 +1,48 @@
{
"name": "react",
"description": "React is a JavaScript library for building user interfaces.",
"keywords": [
"react"
],
"version": "18.3.1",
"homepage": "https://reactjs.org/",
"bugs": "https://github.com/facebook/react/issues",
"license": "MIT",
"files": [
"LICENSE",
"README.md",
"index.js",
"cjs/",
"umd/",
"jsx-runtime.js",
"jsx-dev-runtime.js",
"react.shared-subset.js"
],
"main": "index.js",
"exports": {
".": {
"react-server": "./react.shared-subset.js",
"default": "./index.js"
},
"./package.json": "./package.json",
"./jsx-runtime": "./jsx-runtime.js",
"./jsx-dev-runtime": "./jsx-dev-runtime.js"
},
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",
"directory": "packages/react"
},
"engines": {
"node": ">=0.10.0"
},
"dependencies": {
"loose-envify": "^1.1.0",
"react": "file:"
},
"browserify": {
"transform": [
"loose-envify"
]
}
}

7
board-back/node_modules/react/react.shared-subset.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react.shared-subset.production.min.js');
} else {
module.exports = require('./cjs/react.shared-subset.development.js');
}

3343
board-back/node_modules/react/umd/react.development.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
(function(){'use strict';(function(c,x){"object"===typeof exports&&"undefined"!==typeof module?x(exports):"function"===typeof define&&define.amd?define(["exports"],x):(c=c||self,x(c.React={}))})(this,function(c){function x(a){if(null===a||"object"!==typeof a)return null;a=V&&a[V]||a["@@iterator"];return"function"===typeof a?a:null}function w(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Y(){}function K(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Z(a,b,
e){var m,d={},c=null,h=null;if(null!=b)for(m in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(c=""+b.key),b)aa.call(b,m)&&!ba.hasOwnProperty(m)&&(d[m]=b[m]);var l=arguments.length-2;if(1===l)d.children=e;else if(1<l){for(var f=Array(l),k=0;k<l;k++)f[k]=arguments[k+2];d.children=f}if(a&&a.defaultProps)for(m in l=a.defaultProps,l)void 0===d[m]&&(d[m]=l[m]);return{$$typeof:y,type:a,key:c,ref:h,props:d,_owner:L.current}}function oa(a,b){return{$$typeof:y,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}
function M(a){return"object"===typeof a&&null!==a&&a.$$typeof===y}function pa(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}function N(a,b){return"object"===typeof a&&null!==a&&null!=a.key?pa(""+a.key):b.toString(36)}function B(a,b,e,m,d){var c=typeof a;if("undefined"===c||"boolean"===c)a=null;var h=!1;if(null===a)h=!0;else switch(c){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case y:case qa:h=!0}}if(h)return h=a,d=d(h),a=""===m?"."+
N(h,0):m,ca(d)?(e="",null!=a&&(e=a.replace(da,"$&/")+"/"),B(d,b,e,"",function(a){return a})):null!=d&&(M(d)&&(d=oa(d,e+(!d.key||h&&h.key===d.key?"":(""+d.key).replace(da,"$&/")+"/")+a)),b.push(d)),1;h=0;m=""===m?".":m+":";if(ca(a))for(var l=0;l<a.length;l++){c=a[l];var f=m+N(c,l);h+=B(c,b,e,f,d)}else if(f=x(a),"function"===typeof f)for(a=f.call(a),l=0;!(c=a.next()).done;)c=c.value,f=m+N(c,l++),h+=B(c,b,e,f,d);else if("object"===c)throw b=String(a),Error("Objects are not valid as a React child (found: "+
("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}function C(a,b,e){if(null==a)return a;var c=[],d=0;B(a,c,"","",function(a){return b.call(e,a,d++)});return c}function ra(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=
0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}function O(a,b){var e=a.length;a.push(b);a:for(;0<e;){var c=e-1>>>1,d=a[c];if(0<D(d,b))a[c]=b,a[e]=d,e=c;else break a}}function p(a){return 0===a.length?null:a[0]}function E(a){if(0===a.length)return null;var b=a[0],e=a.pop();if(e!==b){a[0]=e;a:for(var c=0,d=a.length,k=d>>>1;c<k;){var h=2*(c+1)-1,l=a[h],f=h+1,g=a[f];if(0>D(l,e))f<d&&0>D(g,l)?(a[c]=g,a[f]=e,c=f):(a[c]=l,a[h]=e,c=h);else if(f<d&&0>D(g,e))a[c]=g,a[f]=e,c=f;else break a}}return b}
function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=p(r);null!==b;){if(null===b.callback)E(r);else if(b.startTime<=a)E(r),b.sortIndex=b.expirationTime,O(q,b);else break;b=p(r)}}function Q(a){z=!1;P(a);if(!u)if(null!==p(q))u=!0,R(S);else{var b=p(r);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ea(A),A=-1);F=!0;var c=k;try{P(b);for(n=p(q);null!==n&&(!(n.expirationTime>b)||a&&!fa());){var m=n.callback;if("function"===typeof m){n.callback=null;
k=n.priorityLevel;var d=m(n.expirationTime<=b);b=v();"function"===typeof d?n.callback=d:n===p(q)&&E(q);P(b)}else E(q);n=p(q)}if(null!==n)var g=!0;else{var h=p(r);null!==h&&T(Q,h.startTime-b);g=!1}return g}finally{n=null,k=c,F=!1}}function fa(){return v()-ha<ia?!1:!0}function R(a){G=a;H||(H=!0,I())}function T(a,b){A=ja(function(){a(v())},b)}function ka(a){throw Error("act(...) is not supported in production builds of React.");}var y=Symbol.for("react.element"),qa=Symbol.for("react.portal"),sa=Symbol.for("react.fragment"),
ta=Symbol.for("react.strict_mode"),ua=Symbol.for("react.profiler"),va=Symbol.for("react.provider"),wa=Symbol.for("react.context"),xa=Symbol.for("react.forward_ref"),ya=Symbol.for("react.suspense"),za=Symbol.for("react.memo"),Aa=Symbol.for("react.lazy"),V=Symbol.iterator,X={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,c){},enqueueReplaceState:function(a,b,c,m){},enqueueSetState:function(a,b,c,m){}},la=Object.assign,W={};w.prototype.isReactComponent={};w.prototype.setState=function(a,
b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};w.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};Y.prototype=w.prototype;var t=K.prototype=new Y;t.constructor=K;la(t,w.prototype);t.isPureReactComponent=!0;var ca=Array.isArray,aa=Object.prototype.hasOwnProperty,L={current:null},
ba={key:!0,ref:!0,__self:!0,__source:!0},da=/\/+/g,g={current:null},J={transition:null};if("object"===typeof performance&&"function"===typeof performance.now){var Ba=performance;var v=function(){return Ba.now()}}else{var ma=Date,Ca=ma.now();v=function(){return ma.now()-Ca}}var q=[],r=[],Da=1,n=null,k=3,F=!1,u=!1,z=!1,ja="function"===typeof setTimeout?setTimeout:null,ea="function"===typeof clearTimeout?clearTimeout:null,na="undefined"!==typeof setImmediate?setImmediate:null;"undefined"!==typeof navigator&&
void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var H=!1,G=null,A=-1,ia=5,ha=-1,U=function(){if(null!==G){var a=v();ha=a;var b=!0;try{b=G(!0,a)}finally{b?I():(H=!1,G=null)}}else H=!1};if("function"===typeof na)var I=function(){na(U)};else if("undefined"!==typeof MessageChannel){t=new MessageChannel;var Ea=t.port2;t.port1.onmessage=U;I=function(){Ea.postMessage(null)}}else I=function(){ja(U,0)};t={ReactCurrentDispatcher:g,
ReactCurrentOwner:L,ReactCurrentBatchConfig:J,Scheduler:{__proto__:null,unstable_ImmediatePriority:1,unstable_UserBlockingPriority:2,unstable_NormalPriority:3,unstable_IdlePriority:5,unstable_LowPriority:4,unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=k;k=a;try{return b()}finally{k=c}},unstable_next:function(a){switch(k){case 1:case 2:case 3:var b=3;break;default:b=k}var c=k;k=b;try{return a()}finally{k=c}},unstable_scheduleCallback:function(a,
b,c){var e=v();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?e+c:e):c=e;switch(a){case 1:var d=-1;break;case 2:d=250;break;case 5:d=1073741823;break;case 4:d=1E4;break;default:d=5E3}d=c+d;a={id:Da++,callback:b,priorityLevel:a,startTime:c,expirationTime:d,sortIndex:-1};c>e?(a.sortIndex=c,O(r,a),null===p(q)&&a===p(r)&&(z?(ea(A),A=-1):z=!0,T(Q,c-e))):(a.sortIndex=d,O(q,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=
k;return function(){var c=k;k=b;try{return a.apply(this,arguments)}finally{k=c}}},unstable_getCurrentPriorityLevel:function(){return k},unstable_shouldYield:fa,unstable_requestPaint:function(){},unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return p(q)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):
ia=0<a?Math.floor(1E3/a):5},unstable_Profiling:null}};c.Children={map:C,forEach:function(a,b,c){C(a,function(){b.apply(this,arguments)},c)},count:function(a){var b=0;C(a,function(){b++});return b},toArray:function(a){return C(a,function(a){return a})||[]},only:function(a){if(!M(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};c.Component=w;c.Fragment=sa;c.Profiler=ua;c.PureComponent=K;c.StrictMode=ta;c.Suspense=ya;c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=
t;c.act=ka;c.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var e=la({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=L.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var l=a.type.defaultProps;for(f in b)aa.call(b,f)&&!ba.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==l?l[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){l=
Array(f);for(var g=0;g<f;g++)l[g]=arguments[g+2];e.children=l}return{$$typeof:y,type:a.type,key:d,ref:k,props:e,_owner:h}};c.createContext=function(a){a={$$typeof:wa,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:va,_context:a};return a.Consumer=a};c.createElement=Z;c.createFactory=function(a){var b=Z.bind(null,a);b.type=a;return b};c.createRef=function(){return{current:null}};c.forwardRef=function(a){return{$$typeof:xa,
render:a}};c.isValidElement=M;c.lazy=function(a){return{$$typeof:Aa,_payload:{_status:-1,_result:a},_init:ra}};c.memo=function(a,b){return{$$typeof:za,type:a,compare:void 0===b?null:b}};c.startTransition=function(a,b){b=J.transition;J.transition={};try{a()}finally{J.transition=b}};c.unstable_act=ka;c.useCallback=function(a,b){return g.current.useCallback(a,b)};c.useContext=function(a){return g.current.useContext(a)};c.useDebugValue=function(a,b){};c.useDeferredValue=function(a){return g.current.useDeferredValue(a)};
c.useEffect=function(a,b){return g.current.useEffect(a,b)};c.useId=function(){return g.current.useId()};c.useImperativeHandle=function(a,b,c){return g.current.useImperativeHandle(a,b,c)};c.useInsertionEffect=function(a,b){return g.current.useInsertionEffect(a,b)};c.useLayoutEffect=function(a,b){return g.current.useLayoutEffect(a,b)};c.useMemo=function(a,b){return g.current.useMemo(a,b)};c.useReducer=function(a,b,c){return g.current.useReducer(a,b,c)};c.useRef=function(a){return g.current.useRef(a)};
c.useState=function(a){return g.current.useState(a)};c.useSyncExternalStore=function(a,b,c){return g.current.useSyncExternalStore(a,b,c)};c.useTransition=function(){return g.current.useTransition()};c.version="18.3.1"});
})();

View File

@ -0,0 +1,31 @@
/**
* @license React
* react.profiling.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
(function(){'use strict';(function(c,x){"object"===typeof exports&&"undefined"!==typeof module?x(exports):"function"===typeof define&&define.amd?define(["exports"],x):(c=c||self,x(c.React={}))})(this,function(c){function x(a){if(null===a||"object"!==typeof a)return null;a=V&&a[V]||a["@@iterator"];return"function"===typeof a?a:null}function w(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Y(){}function K(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Z(a,b,
e){var m,d={},c=null,h=null;if(null!=b)for(m in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(c=""+b.key),b)aa.call(b,m)&&!ba.hasOwnProperty(m)&&(d[m]=b[m]);var l=arguments.length-2;if(1===l)d.children=e;else if(1<l){for(var f=Array(l),k=0;k<l;k++)f[k]=arguments[k+2];d.children=f}if(a&&a.defaultProps)for(m in l=a.defaultProps,l)void 0===d[m]&&(d[m]=l[m]);return{$$typeof:y,type:a,key:c,ref:h,props:d,_owner:L.current}}function oa(a,b){return{$$typeof:y,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}
function M(a){return"object"===typeof a&&null!==a&&a.$$typeof===y}function pa(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}function N(a,b){return"object"===typeof a&&null!==a&&null!=a.key?pa(""+a.key):b.toString(36)}function B(a,b,e,m,d){var c=typeof a;if("undefined"===c||"boolean"===c)a=null;var h=!1;if(null===a)h=!0;else switch(c){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case y:case qa:h=!0}}if(h)return h=a,d=d(h),a=""===m?"."+
N(h,0):m,ca(d)?(e="",null!=a&&(e=a.replace(da,"$&/")+"/"),B(d,b,e,"",function(a){return a})):null!=d&&(M(d)&&(d=oa(d,e+(!d.key||h&&h.key===d.key?"":(""+d.key).replace(da,"$&/")+"/")+a)),b.push(d)),1;h=0;m=""===m?".":m+":";if(ca(a))for(var l=0;l<a.length;l++){c=a[l];var f=m+N(c,l);h+=B(c,b,e,f,d)}else if(f=x(a),"function"===typeof f)for(a=f.call(a),l=0;!(c=a.next()).done;)c=c.value,f=m+N(c,l++),h+=B(c,b,e,f,d);else if("object"===c)throw b=String(a),Error("Objects are not valid as a React child (found: "+
("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}function C(a,b,e){if(null==a)return a;var c=[],d=0;B(a,c,"","",function(a){return b.call(e,a,d++)});return c}function ra(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=
0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}function O(a,b){var e=a.length;a.push(b);a:for(;0<e;){var c=e-1>>>1,d=a[c];if(0<D(d,b))a[c]=b,a[e]=d,e=c;else break a}}function p(a){return 0===a.length?null:a[0]}function E(a){if(0===a.length)return null;var b=a[0],e=a.pop();if(e!==b){a[0]=e;a:for(var c=0,d=a.length,k=d>>>1;c<k;){var h=2*(c+1)-1,l=a[h],f=h+1,g=a[f];if(0>D(l,e))f<d&&0>D(g,l)?(a[c]=g,a[f]=e,c=f):(a[c]=l,a[h]=e,c=h);else if(f<d&&0>D(g,e))a[c]=g,a[f]=e,c=f;else break a}}return b}
function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=p(r);null!==b;){if(null===b.callback)E(r);else if(b.startTime<=a)E(r),b.sortIndex=b.expirationTime,O(q,b);else break;b=p(r)}}function Q(a){z=!1;P(a);if(!u)if(null!==p(q))u=!0,R(S);else{var b=p(r);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ea(A),A=-1);F=!0;var c=k;try{P(b);for(n=p(q);null!==n&&(!(n.expirationTime>b)||a&&!fa());){var m=n.callback;if("function"===typeof m){n.callback=null;
k=n.priorityLevel;var d=m(n.expirationTime<=b);b=v();"function"===typeof d?n.callback=d:n===p(q)&&E(q);P(b)}else E(q);n=p(q)}if(null!==n)var g=!0;else{var h=p(r);null!==h&&T(Q,h.startTime-b);g=!1}return g}finally{n=null,k=c,F=!1}}function fa(){return v()-ha<ia?!1:!0}function R(a){G=a;H||(H=!0,I())}function T(a,b){A=ja(function(){a(v())},b)}function ka(a){throw Error("act(...) is not supported in production builds of React.");}var y=Symbol.for("react.element"),qa=Symbol.for("react.portal"),sa=Symbol.for("react.fragment"),
ta=Symbol.for("react.strict_mode"),ua=Symbol.for("react.profiler"),va=Symbol.for("react.provider"),wa=Symbol.for("react.context"),xa=Symbol.for("react.forward_ref"),ya=Symbol.for("react.suspense"),za=Symbol.for("react.memo"),Aa=Symbol.for("react.lazy"),V=Symbol.iterator,X={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,c){},enqueueReplaceState:function(a,b,c,m){},enqueueSetState:function(a,b,c,m){}},la=Object.assign,W={};w.prototype.isReactComponent={};w.prototype.setState=function(a,
b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};w.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};Y.prototype=w.prototype;var t=K.prototype=new Y;t.constructor=K;la(t,w.prototype);t.isPureReactComponent=!0;var ca=Array.isArray,aa=Object.prototype.hasOwnProperty,L={current:null},
ba={key:!0,ref:!0,__self:!0,__source:!0},da=/\/+/g,g={current:null},J={transition:null};if("object"===typeof performance&&"function"===typeof performance.now){var Ba=performance;var v=function(){return Ba.now()}}else{var ma=Date,Ca=ma.now();v=function(){return ma.now()-Ca}}var q=[],r=[],Da=1,n=null,k=3,F=!1,u=!1,z=!1,ja="function"===typeof setTimeout?setTimeout:null,ea="function"===typeof clearTimeout?clearTimeout:null,na="undefined"!==typeof setImmediate?setImmediate:null;"undefined"!==typeof navigator&&
void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var H=!1,G=null,A=-1,ia=5,ha=-1,U=function(){if(null!==G){var a=v();ha=a;var b=!0;try{b=G(!0,a)}finally{b?I():(H=!1,G=null)}}else H=!1};if("function"===typeof na)var I=function(){na(U)};else if("undefined"!==typeof MessageChannel){t=new MessageChannel;var Ea=t.port2;t.port1.onmessage=U;I=function(){Ea.postMessage(null)}}else I=function(){ja(U,0)};t={ReactCurrentDispatcher:g,
ReactCurrentOwner:L,ReactCurrentBatchConfig:J,Scheduler:{__proto__:null,unstable_ImmediatePriority:1,unstable_UserBlockingPriority:2,unstable_NormalPriority:3,unstable_IdlePriority:5,unstable_LowPriority:4,unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=k;k=a;try{return b()}finally{k=c}},unstable_next:function(a){switch(k){case 1:case 2:case 3:var b=3;break;default:b=k}var c=k;k=b;try{return a()}finally{k=c}},unstable_scheduleCallback:function(a,
b,c){var e=v();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?e+c:e):c=e;switch(a){case 1:var d=-1;break;case 2:d=250;break;case 5:d=1073741823;break;case 4:d=1E4;break;default:d=5E3}d=c+d;a={id:Da++,callback:b,priorityLevel:a,startTime:c,expirationTime:d,sortIndex:-1};c>e?(a.sortIndex=c,O(r,a),null===p(q)&&a===p(r)&&(z?(ea(A),A=-1):z=!0,T(Q,c-e))):(a.sortIndex=d,O(q,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=
k;return function(){var c=k;k=b;try{return a.apply(this,arguments)}finally{k=c}}},unstable_getCurrentPriorityLevel:function(){return k},unstable_shouldYield:fa,unstable_requestPaint:function(){},unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return p(q)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):
ia=0<a?Math.floor(1E3/a):5},unstable_Profiling:null}};c.Children={map:C,forEach:function(a,b,c){C(a,function(){b.apply(this,arguments)},c)},count:function(a){var b=0;C(a,function(){b++});return b},toArray:function(a){return C(a,function(a){return a})||[]},only:function(a){if(!M(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};c.Component=w;c.Fragment=sa;c.Profiler=ua;c.PureComponent=K;c.StrictMode=ta;c.Suspense=ya;c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=
t;c.act=ka;c.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var e=la({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=L.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var l=a.type.defaultProps;for(f in b)aa.call(b,f)&&!ba.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==l?l[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){l=
Array(f);for(var g=0;g<f;g++)l[g]=arguments[g+2];e.children=l}return{$$typeof:y,type:a.type,key:d,ref:k,props:e,_owner:h}};c.createContext=function(a){a={$$typeof:wa,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:va,_context:a};return a.Consumer=a};c.createElement=Z;c.createFactory=function(a){var b=Z.bind(null,a);b.type=a;return b};c.createRef=function(){return{current:null}};c.forwardRef=function(a){return{$$typeof:xa,
render:a}};c.isValidElement=M;c.lazy=function(a){return{$$typeof:Aa,_payload:{_status:-1,_result:a},_init:ra}};c.memo=function(a,b){return{$$typeof:za,type:a,compare:void 0===b?null:b}};c.startTransition=function(a,b){b=J.transition;J.transition={};try{a()}finally{J.transition=b}};c.unstable_act=ka;c.useCallback=function(a,b){return g.current.useCallback(a,b)};c.useContext=function(a){return g.current.useContext(a)};c.useDebugValue=function(a,b){};c.useDeferredValue=function(a){return g.current.useDeferredValue(a)};
c.useEffect=function(a,b){return g.current.useEffect(a,b)};c.useId=function(){return g.current.useId()};c.useImperativeHandle=function(a,b,c){return g.current.useImperativeHandle(a,b,c)};c.useInsertionEffect=function(a,b){return g.current.useInsertionEffect(a,b)};c.useLayoutEffect=function(a,b){return g.current.useLayoutEffect(a,b)};c.useMemo=function(a,b){return g.current.useMemo(a,b)};c.useReducer=function(a,b,c){return g.current.useReducer(a,b,c)};c.useRef=function(a){return g.current.useRef(a)};
c.useState=function(a){return g.current.useState(a)};c.useSyncExternalStore=function(a,b,c){return g.current.useSyncExternalStore(a,b,c)};c.useTransition=function(){return g.current.useTransition()};c.version="18.3.1"});
})();

54
board-back/package-lock.json generated Normal file
View File

@ -0,0 +1,54 @@
{
"name": "board-back",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"react-daum-postcode": "^3.1.3"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT",
"peer": true
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-daum-postcode": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/react-daum-postcode/-/react-daum-postcode-3.1.3.tgz",
"integrity": "sha512-qTyzUb1BeszPFO4FXSj6p83Wrn5Zpo6YqI2EZ46XSVRZT+du9CrKg9p3KshBRFKYxXmFE1Mv7wEynzXdRFNlmQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.8.0"
}
}
}
}

5
board-back/package.json Normal file
View File

@ -0,0 +1,5 @@
{
"dependencies": {
"react-daum-postcode": "^3.1.3"
}
}

View File

@ -0,0 +1,28 @@
package com.eogns.board_back.common;
public interface ResponseCode {
//HTTP Status 200
public static final String SUCCESS = "SU"; //인터페이스에선 그냥 선언해도 public static final로 인식
//HTTP Status 400
public static final String VALIDATION_FAILED = "VF";
public static final String DUPLICATE_EMAIL = "DE";
public static final String DUPLICATE_NICKNAME = "DN";
public static final String DUPLICATE_TEL_NUMBER = "DT";
public static final String NOT_EXISTED_USER = "NU";
public static final String NOT_EXISTED_BOARD = "NB";
//HTTP Status 401
public static final String SIGN_IN_FAIL = "SF";
public static final String AUTHORIZATION_FAIL = "AF";
//HTTP Status 403
public static final String NO_PERMISSON = "NP";
//HTTP Status 500
public static final String DATABASE_ERROR = "DBE";
}

View File

@ -0,0 +1,18 @@
package com.eogns.board_back.common;
public class ResponseMessage {
public static final String SUCCESS = "Success"; //인터페이스에선 그냥 선언해도 public static final로 인식
public static final String VALIDATION_FAILED = "유효성 인증 실패";
public static final String DUPLICATE_EMAIL = "중복된 이메일";
public static final String DUPLICATE_NICKNAME = "중복된 닉네임";
public static final String DUPLICATE_TEL_NUMBER = "중복된 전화번호";
public static final String NOT_EXISTED_USER = "존재하지 않는 유저";
public static final String NOT_EXISTED_BOARD = "존재하지 않는 게시물";
public static final String SIGN_IN_FAIL = "로그인 실패";
public static final String AUTHORIZATION_FAIL = "인증 실패";
public static final String NO_PERMISSON = "권한 없음";
public static final String DATABASE_ERROR = "데이터베이스 에러";
}

View File

@ -0,0 +1,171 @@
package com.eogns.board_back.config;
import java.io.IOException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.eogns.board_back.filter.jwtAuthenticationFilter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
@SuppressWarnings("rawtypes") // 이거 빠른수정으로 추가
private final jwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors(cors -> cors
.configurationSource(corsConfigurationSource())
)
.csrf(CsrfConfigurer::disable)
.httpBasic(HttpBasicConfigurer::disable)
.sessionManagement(sessionManagement -> sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(request -> request
.requestMatchers("/", "/api/v1/auth/**", "/api/v1/search/**", "/file/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/board/**", "/api/v1/user/*").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(new FailedAuthenticationEntryPoint())
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
@Bean
protected CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("*"); // 모든 출처에 대해서 허용하려면 인증 정보가 true이면 안된다.
configuration.addAllowedMethod("*"); // 모든 HTTP 메서드 허용
configuration.addAllowedHeader("*"); // 모든 헤더 허용
//configuration.setAllowCredentials(true); // 인증 정보 허용
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
class FailedAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"code\": \"AF\", \"message\": \"Authorization Failed.\"}");
}
}
/* package com.eogns.board_back.config;
import java.io.IOException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.eogns.board_back.filter.jwtAuthenticationFilter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
@SuppressWarnings("rawtypes") // 이거 빠른수정으로 추가
private final jwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity
.cors(cors -> cors
.configurationSource(corsConfigurationSource())
)
.csrf(CsrfConfigurer::disable)
.httpBasic(HttpBasicConfigurer::disable)
.sessionManagement(sessionManagement -> sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(request -> request
.requestMatchers("/","/api/v1/auth/**", "api/v1/search/**","/file/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/board/**", "/api/v1/user/*").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(new FailedAuthenticationEntryPoint())
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
@Bean
protected CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("*");
configuration.addAllowedMethod("*");
configuration.addExposedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
class FailedAuthenticationEntryPoint implements AuthenticationEntryPoint{
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"code:\": \"AF\", \"message\": \"Authorizion Filed. \"}");
}
}
*/

View File

@ -0,0 +1,45 @@
package com.eogns.board_back.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.eogns.board_back.service.AuthService;
import jakarta.validation.Valid;
import com.eogns.board_back.dto.request.auth.SignInRequestDto;
import com.eogns.board_back.dto.response.auth.SignInResponseDto;
import com.eogns.board_back.dto.request.auth.SignUpRequestDto;
import com.eogns.board_back.dto.response.auth.SignUpResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@RestController
@RequestMapping("/api/v1/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthService authService;
@PostMapping("/sign-up")
public ResponseEntity<? super SignUpResponseDto> signUp(
@RequestBody @Valid SignUpRequestDto requestBody
) {
ResponseEntity<? super SignUpResponseDto> response = authService.signUp(requestBody);
return response;
}
@PostMapping("/sign-in")
public ResponseEntity<? super SignInResponseDto> signIn(
@RequestBody @Valid SignInRequestDto requestBody
) {
ResponseEntity<? super SignInResponseDto> response = authService.signIn(requestBody);
return response;
}
}

View File

@ -0,0 +1,118 @@
package com.eogns.board_back.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.eogns.board_back.dto.request.board.PostBoardRequestDto;
import com.eogns.board_back.dto.request.board.PostCommentRequestDto;
import com.eogns.board_back.dto.response.board.PostBoardResponseDto;
import com.eogns.board_back.dto.response.board.PostCommentResponseDto;
import com.eogns.board_back.dto.response.board.PutFavoriteResponseDto;
import com.eogns.board_back.service.BoardService;
import com.mysql.cj.x.protobuf.MysqlxCrud.Delete;
import com.eogns.board_back.dto.response.board.DeleteBoardResponseDto;
import com.eogns.board_back.dto.response.board.GetBoardResponseDto;
import com.eogns.board_back.dto.response.board.GetCommentListResponseDto;
import com.eogns.board_back.dto.response.board.GetFavoriteListResponseDto;
import com.eogns.board_back.dto.response.board.IncreaseViewCountResponseDto;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
@RestController
@RequestMapping("/api/v1/board")
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;
@GetMapping("/{boardNumber}")
public ResponseEntity<? super GetBoardResponseDto> getBoard(
@PathVariable("boardNumber") Integer boardNumber
){
ResponseEntity<? super GetBoardResponseDto> response = boardService.getBoard(boardNumber);
return response;
}
public String getMethodName(@RequestParam String param) {
return new String();
}
@GetMapping("{boardNumber}/favorite-list")
public ResponseEntity<? super GetFavoriteListResponseDto> getFavoriteList(
@PathVariable("boardNumber") Integer boardNumber
) {
ResponseEntity<? super GetFavoriteListResponseDto> response = boardService.getFavoriteList(boardNumber);
return response;
}
@GetMapping("/{boardNumber}/comment-list")
public ResponseEntity<? super GetCommentListResponseDto> getCommentList(
@PathVariable("boardNumber") Integer boardNumber
) {
ResponseEntity<? super GetCommentListResponseDto> response = boardService.getCommentList(boardNumber);
return response;
}
@GetMapping("/{boardNumber}/increase-view-count")
public ResponseEntity<? super IncreaseViewCountResponseDto> increaseViewCount(
@PathVariable("boardNumber") Integer boardNumber
){
ResponseEntity<? super IncreaseViewCountResponseDto> response = boardService.increaseViewCount(boardNumber);
return response;
}
@PostMapping("")
public ResponseEntity<? super PostBoardResponseDto> postBoard(
@RequestBody @Valid PostBoardRequestDto requseBoby,
@AuthenticationPrincipal String email
) {
ResponseEntity<? super PostBoardResponseDto> response = boardService.postBoard(requseBoby, email);
return response;
}
@PostMapping("/{boardNumber}/comment")
public ResponseEntity<? super PostCommentResponseDto> postComment(
@RequestBody @Valid PostCommentRequestDto requsetBody,
@PathVariable("boardNumber") Integer boardNumber,
@AuthenticationPrincipal String email
){
ResponseEntity<? super PostCommentResponseDto> response = boardService.postComment(requsetBody,boardNumber,email);
return response;
}
@PutMapping("/{boardNumber}/favorite")
public ResponseEntity<? super PutFavoriteResponseDto> putFavorite(
@PathVariable("boardNumber") Integer boardNumber,
@AuthenticationPrincipal String email
){
ResponseEntity<? super PutFavoriteResponseDto> response = boardService.putFavorite(boardNumber, email);
return response;
}
@DeleteMapping("/{boardNumber}")
public ResponseEntity<? super DeleteBoardResponseDto> deleteBoard(
@PathVariable("boardNumber") Integer boardNumber,
@AuthenticationPrincipal String email
) {
ResponseEntity<? super DeleteBoardResponseDto> response = boardService.deleteBoard(boardNumber, email);
return response;
}
}

View File

@ -0,0 +1,30 @@
package com.eogns.board_back.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.eogns.board_back.dto.response.user.GetSignInUserResponseDto;
import com.eogns.board_back.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/user")
public class UserController {
private final UserService userService;
@GetMapping("")
public ResponseEntity<? super GetSignInUserResponseDto> getSignInUser(
@AuthenticationPrincipal String email
){
ResponseEntity<? super GetSignInUserResponseDto> response = userService.getSinInuser(email);
return response;
}
}

View File

@ -0,0 +1,45 @@
package com.eogns.board_back.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.eogns.board_back.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class fileController {
private final FileService fileService;
@PostMapping("/upload")
public String upload(
@RequestParam("file") MultipartFile file
) {
String url = fileService.uplad(file);
return url;
}
@GetMapping(value = "{fileName}", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
public Resource getImage(
@PathVariable("fileName") String fileName
) {
Resource resource = fileService.getImage(fileName);
return resource;
}
}

View File

@ -0,0 +1,21 @@
package com.eogns.board_back.dto.object;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class BoardListItem {
private int BoardNumber;
private String title;
private String content;
private String boardTitleImage;
private int favoriteCount;
private int commentCount;
private int viewCount;
private String writeDateTime;
private String writerNickName;
private String writerProfileImage;
}

View File

@ -0,0 +1,37 @@
package com.eogns.board_back.dto.object;
import java.util.ArrayList;
import java.util.List;
import com.eogns.board_back.repository.resultSet.GetCommentListResultSet;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CommentListItem {
private String nickname;
private String profileImage;
private String writeDatetime;
private String content;
public CommentListItem(GetCommentListResultSet resultSet){
this.nickname = resultSet.getNickname();
this.profileImage = resultSet.getProfileImage();
this.writeDatetime = resultSet.getWriteDatetime();
this.content = resultSet.getContent();
}
public static List<CommentListItem> copyList(List<GetCommentListResultSet> resultSets){
List<CommentListItem> list = new ArrayList<>();
for(GetCommentListResultSet resultSet: resultSets){
CommentListItem commentListItem = new CommentListItem(resultSet);
list.add(commentListItem);
}
return list;
}
}

View File

@ -0,0 +1,35 @@
package com.eogns.board_back.dto.object;
import java.util.ArrayList;
import java.util.List;
import com.eogns.board_back.repository.resultSet.GetFavoriteListResultSet;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class FavoriteListItem{
private String email;
private String nickname;
private String profileImage;
public FavoriteListItem(GetFavoriteListResultSet resultSet){
this.email = resultSet.getEmail();
this.nickname = resultSet.getNickname();
this.profileImage = resultSet.getProfileImage();
}
public static List<FavoriteListItem> copyList(List<GetFavoriteListResultSet> resultSets){
List<FavoriteListItem> list = new ArrayList<>();
for(GetFavoriteListResultSet resultSet: resultSets){
FavoriteListItem favoriteListItem = new FavoriteListItem(resultSet);
list.add(favoriteListItem);
}
return list;
}
}

View File

@ -0,0 +1,17 @@
package com.eogns.board_back.dto.request.auth;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class SignInRequestDto {
@NotBlank
private String email;
@NotBlank
private String password;
}

View File

@ -0,0 +1,39 @@
package com.eogns.board_back.dto.request.auth;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class SignUpRequestDto {
@NotBlank @Email /* 문자열에서 NULL이 아니여야하고 공백이 아니여아하는 조건 ex) '', ' ' */
private String email;
@NotBlank @Size(min=8, max=20)
private String password;
@NotBlank
private String nickname;
@NotBlank @Pattern(regexp="^[0-9]{11,13}$")
private String telNumber;
@NotBlank
private String address;
private String addressDetail;
@NotNull @AssertTrue
private Boolean agreedPersonal;
}

View File

@ -0,0 +1,23 @@
package com.eogns.board_back.dto.request.board;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Getter
@Setter
@NoArgsConstructor
public class PostBoardRequestDto {
@NotBlank
private String title;
@NotBlank
private String content;
@NotNull
private List<String> boardImageList;
}

View File

@ -0,0 +1,16 @@
package com.eogns.board_back.dto.request.board;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class PostCommentRequestDto {
@NotBlank
private String content;
}

View File

@ -0,0 +1,80 @@
/* package com.eogns.board_back.dto.response;
import org.springframework.http.HttpStatus;
//import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.request.auth.SignInRequestDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class ResponseDto {
private String code;
private String message;
public static ResponseEntity<? super SignInRequestDto> databaseError(){
ResponseDto responseBody = new ResponseDto(ResponseCode.DATABASE_ERROR, ResponseMessage.DATABASE_ERROR);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseBody);
}
}
교통 70000 동
전,가,통 85000 카
식 600000 토
주 500000 현
적 50000 카
월 340000 현
담 50000 토
여 180000
const a = 125;
const b = 1.8;
const c = 3.5;
const d = b + c;
const f = 34;
-363790
55
const T = 187
const e = 169.5;
18.5
387210
71.1
*/
package com.eogns.board_back.dto.response;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class ResponseDto {
private String code;
private String message;
public static ResponseEntity<ResponseDto> databaseError() {
ResponseDto responseBody = new ResponseDto(ResponseCode.DATABASE_ERROR, ResponseMessage.DATABASE_ERROR);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseBody);
}
public static ResponseEntity<ResponseDto> vaildationFailed(){
ResponseDto responseBody = new ResponseDto(ResponseCode.VALIDATION_FAILED, ResponseMessage.VALIDATION_FAILED);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseBody);
}
}

View File

@ -0,0 +1,33 @@
package com.eogns.board_back.dto.response.auth;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class SignInResponseDto extends ResponseDto{
private String token;
private int expirationTime;
private SignInResponseDto(String token){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
this.token = token;
this.expirationTime = 3600;
}
public static ResponseEntity<SignInResponseDto> success(String token){
SignInResponseDto result = new SignInResponseDto(token);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> signInFail(){
ResponseDto result = new ResponseDto(ResponseCode.SIGN_IN_FAIL, ResponseMessage.SIGN_IN_FAIL);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
}
}

View File

@ -0,0 +1,39 @@
package com.eogns.board_back.dto.response.auth;
import org.springframework.http.HttpStatus;
//import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class SignUpResponseDto extends ResponseDto{
private SignUpResponseDto(){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<SignUpResponseDto> success(){
SignUpResponseDto result = new SignUpResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> duplicateEmail(){
ResponseDto result = new ResponseDto(ResponseCode.DUPLICATE_EMAIL, ResponseMessage.DUPLICATE_EMAIL);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> duplicateNickname(){
ResponseDto result = new ResponseDto(ResponseCode.DUPLICATE_NICKNAME, ResponseMessage.DUPLICATE_NICKNAME);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> duplicateTelNumber(){
ResponseDto result = new ResponseDto(ResponseCode.DUPLICATE_TEL_NUMBER, ResponseMessage.DUPLICATE_TEL_NUMBER);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
}

View File

@ -0,0 +1,33 @@
package com.eogns.board_back.dto.response.board;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class DeleteBoardResponseDto extends ResponseDto{
private DeleteBoardResponseDto(){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<DeleteBoardResponseDto> success(){
DeleteBoardResponseDto result = new DeleteBoardResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD, ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> noExistuser(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> noPermission(){
ResponseDto result = new ResponseDto(ResponseCode.NO_PERMISSON, ResponseMessage.NO_PERMISSON);
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(result);
}
}

View File

@ -0,0 +1,60 @@
package com.eogns.board_back.dto.response.board;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import com.eogns.board_back.entity.ImageEntity;
import com.eogns.board_back.repository.resultSet.GetBoardResultSet;
import lombok.Getter;
@Getter
public class GetBoardResponseDto extends ResponseDto{
private int boardNumber;
private String title;
private String content;
private List<String> boardImageList;
private String writeDatetime;
private String writerEmail;
private String writerNickname;
private String writerProfileImage;
private GetBoardResponseDto(GetBoardResultSet resultSet, List<ImageEntity> imageEntities){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
List<String> boardImageList = new ArrayList<>();
for(ImageEntity imageEntity: imageEntities){
String boardImage = imageEntity.getImage();
boardImageList.add(boardImage);
}
this.boardNumber = resultSet.getBoardNumber();
this.title = resultSet.getTitle();
this.content = resultSet.getContent();
this.boardImageList = boardImageList;
this.writeDatetime = resultSet.getWriteDatetime();
this.writerEmail = resultSet.getWriterEmail();
this.writerNickname = resultSet.getWriterNickname();
this.writerProfileImage = resultSet.getWriterProfileImage();
}
public static ResponseEntity<GetBoardResponseDto> success(GetBoardResultSet resultSet, List<ImageEntity> imageEntities){
GetBoardResponseDto result = new GetBoardResponseDto(resultSet, imageEntities);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD, ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
}

View File

@ -0,0 +1,39 @@
package com.eogns.board_back.dto.response.board;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.object.CommentListItem;
import com.eogns.board_back.dto.response.ResponseDto;
import com.eogns.board_back.repository.resultSet.GetCommentListResultSet;
import lombok.Getter;
@Getter
public class GetCommentListResponseDto extends ResponseDto{
private List<CommentListItem> commentList;
private GetCommentListResponseDto(List<GetCommentListResultSet> resultSets){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
this.commentList = CommentListItem.copyList(resultSets);
}
public static ResponseEntity<GetCommentListResponseDto> success(List<GetCommentListResultSet> resultSets){
GetCommentListResponseDto result = new GetCommentListResponseDto(resultSets);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard (){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD,ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
/* public static ResponseEntity<ResponseDto> noExistUser (){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER,ResponseMessage.NOT_EXISTED_USER);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
} */
}

View File

@ -0,0 +1,34 @@
package com.eogns.board_back.dto.response.board;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.object.FavoriteListItem;
import com.eogns.board_back.dto.response.ResponseDto;
import com.eogns.board_back.repository.resultSet.GetFavoriteListResultSet;
import lombok.Getter;
@Getter
public class GetFavoriteListResponseDto extends ResponseDto{
private List<FavoriteListItem> favoriteList;
private GetFavoriteListResponseDto(List<GetFavoriteListResultSet> resultSets){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
this.favoriteList = FavoriteListItem.copyList(resultSets);
}
public static ResponseEntity<GetFavoriteListResponseDto> success(List<GetFavoriteListResultSet> resultSets){
GetFavoriteListResponseDto result = new GetFavoriteListResponseDto(resultSets);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD, ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
}

View File

@ -0,0 +1,24 @@
package com.eogns.board_back.dto.response.board;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
public class IncreaseViewCountResponseDto extends ResponseDto{
private IncreaseViewCountResponseDto(){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<IncreaseViewCountResponseDto> success(){
IncreaseViewCountResponseDto result = new IncreaseViewCountResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD, ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
}

View File

@ -0,0 +1,27 @@
package com.eogns.board_back.dto.response.board;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class PostBoardResponseDto extends ResponseDto{
private PostBoardResponseDto(){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<PostBoardResponseDto> success(){
PostBoardResponseDto result = new PostBoardResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> notExisuser(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER );
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
}
}

View File

@ -0,0 +1,29 @@
package com.eogns.board_back.dto.response.board;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class PostCommentResponseDto extends ResponseDto{
private PostCommentResponseDto() {
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<PostCommentResponseDto> success(){
PostCommentResponseDto result = new PostCommentResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD ,ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> noExistUser(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER ,ResponseMessage.NOT_EXISTED_USER);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
}
}

View File

@ -0,0 +1,32 @@
package com.eogns.board_back.dto.response.board;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import lombok.Getter;
@Getter
public class PutFavoriteResponseDto extends ResponseDto{
private PutFavoriteResponseDto(){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
}
public static ResponseEntity<PutFavoriteResponseDto> success(){
PutFavoriteResponseDto result = new PutFavoriteResponseDto();
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> noExistBoard(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_BOARD, ResponseMessage.NOT_EXISTED_BOARD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
public static ResponseEntity<ResponseDto> noExistUser() {
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
}
}

View File

@ -0,0 +1,37 @@
package com.eogns.board_back.dto.response.user;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.eogns.board_back.common.ResponseCode;
import com.eogns.board_back.common.ResponseMessage;
import com.eogns.board_back.dto.response.ResponseDto;
import com.eogns.board_back.entity.UserEntity;
import lombok.Getter;
@Getter
public class GetSignInUserResponseDto extends ResponseDto{
private String email;
private String nickname;
private String profileImage;
private GetSignInUserResponseDto(UserEntity userEntity){
super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS);
this.email = userEntity.getEmail();
this.nickname = userEntity.getNickname();
this.profileImage = userEntity.getProfileImage();
}
public static ResponseEntity<GetSignInUserResponseDto> success(UserEntity userEntity){
GetSignInUserResponseDto result = new GetSignInUserResponseDto(userEntity);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
public static ResponseEntity<ResponseDto> notExisUser(){
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);
}
}

View File

@ -0,0 +1,115 @@
package com.eogns.board_back.entity;
import com.eogns.board_back.dto.request.board.PostBoardRequestDto;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.Instant;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "board")
@Table(name="board")
public class BoardEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) /* Auto increment 역할 */
private int boardNumber ;
private String title;
private String content;
private String writeDatetime;
private int favoriteCount;
private int commentCount;
private int viewCount;
private String writerEmail;
public BoardEntity(PostBoardRequestDto dto, String email){
Date now = Date.from(Instant.now());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String writeDatetime = simpleDateFormat.format(now) ;
this.title = dto.getTitle();
this.content = dto.getContent();
this.writeDatetime = writeDatetime;
this.favoriteCount = 0;
this.commentCount = 0;
this.viewCount = 0;
this.writerEmail = email;
}
public void imcreaseViewCount() {
this.viewCount++;
}
public void increaseFavoriteCount(){
this.favoriteCount++;
}
public void increaseCommentCount(){
this.commentCount++;
}
public void decreaseFavoriteCount(){
this.favoriteCount--;
}
}
//import java.time.LocalDateTime;
//import java.time.format.DateTimeFormatter;
//
//@Getter
//@NoArgsConstructor
//@AllArgsConstructor
//@Entity(name = "board")
//@Table(name="board")
//public class BoardEntity {
// @Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// private int boardNumber;
// private String title;
// private String content;
// private LocalDateTime writeDatetime;
// private int favoriteCount;
// private int commentCount;
// private int viewCount;
// private String writerEmail;
//
// public BoardEntity(PostBoardRequestDto dto, String email) {
// this.title = dto.getTitle();
// this.content = dto.getContent();
// this.writeDatetime = LocalDateTime.now(); // 현재 시간 저장
// this.favoriteCount = 0;
// this.commentCount = 0;
// this.viewCount = 0;
// this.writerEmail = email;
// }
//
// public void imcreaseViewCount() {
// this.viewCount++;
// }
//
// public void increaseFavoriteCount() {
// this.favoriteCount++;
// }
//
// public void increaseCommentCount() {
// this.commentCount++;
// }
//
// public void decreaseFavoriteCount() {
// this.favoriteCount--;
// }
//}

View File

@ -0,0 +1,29 @@
package com.eogns.board_back.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name="board_list_view")
@Table(name="board_list_view")
public class BoardListVeiwEntity {
@Id
private int boardNumber;
private String title;
private String content;
private String titleImage;
private int viewCount;
private int favoriteCount;
private int commentCount;
private String writeDatetime;
private String writerEmail;
private String writerNickname;
private String writerProFileImage;
}

View File

@ -0,0 +1,44 @@
package com.eogns.board_back.entity;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.Instant;
import com.eogns.board_back.dto.request.board.PostCommentRequestDto;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name="comment")
@Table(name="comment")
public class CommentEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private int commentNumber;
private String content;
private String writeDatetime;
private String userEmail;
private int boardNumber;
public CommentEntity (PostCommentRequestDto dto, Integer boardNumber, String email){
Date now = Date.from(Instant.now());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String writeDatetime = simpleDateFormat.format(now);
this.content = dto.getContent();
this.writeDatetime = writeDatetime;
this.userEmail = email;
this.boardNumber = boardNumber;
}
}

View File

@ -0,0 +1,25 @@
package com.eogns.board_back.entity;
import com.eogns.board_back.entity.primaryKey.FavoritePK;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name="favorite")
@Table(name="favorite")
@IdClass(FavoritePK.class)
public class FavoriteEntity {
@Id
private String userEmail;
@Id
private int boardNumber;
}

View File

@ -0,0 +1,28 @@
package com.eogns.board_back.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name="image")
@Table(name="image")
public class ImageEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private int sequence;
private int boardNumber;
private String image;
public ImageEntity(int boardNumber, String image){
this.boardNumber = boardNumber;
this.image = image;
}
}

View File

@ -0,0 +1,23 @@
package com.eogns.board_back.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name="search_log") /* 엔티티의 기본 디폴트 값은 그냥 클래스 이름인데 여기는 이름이 다르니까 지정함 */
@Table(name="search_log")
public class SearchLogEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private int sequence;
private String searchWord;
private String relationWord;
private boolean relation;
}

View File

@ -0,0 +1,43 @@
package com.eogns.board_back.entity;
//import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
import com.eogns.board_back.dto.request.auth.SignUpRequestDto;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "user")
@Table(name="user")
public class UserEntity{
@Id
private String email;
private String password;
private String nickname;
private String telNumber;
private String address;
private String addressDetail;
private String profileImage;
private boolean agreedPersonal;
public UserEntity(SignUpRequestDto dto){
this.email = dto.getEmail();
this.password = dto.getPassword();
this.nickname = dto.getNickname();
this.telNumber = dto.getTelNumber();
this.address = dto.getAddress();
this.addressDetail = dto.getAddressDetail();
this.agreedPersonal = dto.getAgreedPersonal();
}
}

View File

@ -0,0 +1,21 @@
package com.eogns.board_back.entity.primaryKey;
import java.io.Serializable;
import jakarta.persistence.Column;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class FavoritePK implements Serializable{
@Column(name="user_email")
private String userEmail;
@Column(name="board_number")
private int boardNumber;
}

View File

@ -0,0 +1,19 @@
package com.eogns.board_back.exception;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.eogns.board_back.dto.response.ResponseDto;
@RestControllerAdvice
public class BadRequestExceptionHandler {
@ExceptionHandler({MethodArgumentNotValidException.class, HttpMessageNotReadableException.class})
public ResponseEntity<ResponseDto> vaildationExceptionHandler(Exception exception){
return ResponseDto.vaildationFailed();
}
}

View File

@ -0,0 +1,80 @@
package com.eogns.board_back.filter;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.eogns.board_back.provider.jwtProvider;
import org.springframework.util.StringUtils;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class jwtAuthenticationFilter<JwtProvider> extends OncePerRequestFilter{
private final jwtProvider jwtProvider;
@SuppressWarnings("null")
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String token =parseBearerToken(request);
if (token == null) {
filterChain.doFilter(request, response);
return;
}
String email = jwtProvider.validate(token);
if (email == null) {
filterChain.doFilter(request, response);
return;
}
AbstractAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(email, null, AuthorityUtils.NO_AUTHORITIES);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authenticationToken);
SecurityContextHolder.setContext(securityContext);
} catch (Exception exception) {
exception.printStackTrace();
}
filterChain.doFilter(request, response);
}
private String parseBearerToken(HttpServletRequest request){
String authorization = request.getHeader("Authorization");
boolean hasAuthorization = StringUtils.hasText(authorization);
if (!hasAuthorization) return null;
boolean isBearer = authorization.startsWith("Bearer ");
if(!isBearer) return null;
String token = authorization.substring(7);
return token;
}
}

View File

@ -0,0 +1,56 @@
package com.eogns.board_back.provider;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
@Component
public class jwtProvider {
@Value("${secret-key}")
private String secretKey;
public String create(String email){
Date expiredDate = Date.from(Instant.now().plus(1, ChronoUnit.HOURS));
Key key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
String jwt = Jwts.builder()
.signWith(key, SignatureAlgorithm.HS256)
.setSubject(email).setIssuedAt(new Date()).setExpiration(expiredDate)
.compact();
return jwt;
}
public String validate(String jwt){
Claims claims = null;
Key key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
try {
claims = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(jwt)
.getBody();
} catch (Exception exception) {
exception.printStackTrace();
return null;
}
return claims.getSubject();
}
}

View File

@ -0,0 +1,11 @@
package com.eogns.board_back.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.BoardListVeiwEntity;
@Repository
public interface BoardListViewRepository extends JpaRepository<BoardListVeiwEntity, Integer>{
}

View File

@ -0,0 +1,35 @@
package com.eogns.board_back.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.BoardEntity;
import com.eogns.board_back.repository.resultSet.GetBoardResultSet;
@Repository
public interface BoardRepository extends JpaRepository<BoardEntity, Integer>{
boolean existsByBoardNumber(Integer boardNumber);
BoardEntity findByBoardNumber(Integer boardNumber);
@Query(
value =
"SELECT " +
"B.board_number AS board_number, "+
"B.title AS title, "+
"B.content AS content, "+
"B.write_datetime AS writerdatetime, "+
"B.writer_email AS writeremail, "+
"U.nickname AS writernickname, "+
"U.profile_image AS writerprofileimage "+
"FROM board AS B "+
"INNER JOIN user AS U "+
"ON B.writer_email = U.email "+
"WHERE board_number = ?1 ", /* 매개변수의 첫번째 값을 ?1 에 넣음 */
nativeQuery = true
)
GetBoardResultSet getBoard(Integer boardNumber);
}

View File

@ -0,0 +1,36 @@
package com.eogns.board_back.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.CommentEntity;
import com.eogns.board_back.repository.resultSet.GetCommentListResultSet;
import jakarta.transaction.Transactional;
@Repository
public interface CommentRepository extends JpaRepository<CommentEntity, Integer>{
@Query(
value =
"SELECT " +
" U.nickname AS nickname, " +
" U.profile_image AS profile_image, " +
" C.write_datetime AS writedatetime, " +
" C.content AS content " +
"FROM comment AS C " +
"INNER JOIN user AS U " +
"ON C.user_email = U.email " +
"WHERE C.board_number = ?1 " +
"ORDER BY write_datetime DESC ",
nativeQuery = true
)
List<GetCommentListResultSet> getCommentList(Integer boardNumber);
@Transactional
void deleteByBoardNumber(Integer boardNumber);
}

View File

@ -0,0 +1,36 @@
package com.eogns.board_back.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.FavoriteEntity;
import com.eogns.board_back.entity.primaryKey.FavoritePK;
import com.eogns.board_back.repository.resultSet.GetFavoriteListResultSet;
import jakarta.transaction.Transactional;
@Repository
public interface FavoriteRepository extends JpaRepository<FavoriteEntity, FavoritePK>{
FavoriteEntity findByBoardNumberAndUserEmail(Integer boardNumber, String userEamil);
@Query(
value =
"SELECT " +
" U.email AS email, " +
" U.nickname AS nickname, " +
" U.profile_image AS profileImage " +
"FROM favorite AS F " +
"INNER JOIN user AS U " +
"ON F.user_email = U.email " +
"WHERE F.board_number = ?1",
nativeQuery = true
)
List<GetFavoriteListResultSet> GetFavoriteList(Integer boardNumber);
@Transactional
void deleteByBoardNumber(Integer boardNumber);
}

View File

@ -0,0 +1,20 @@
package com.eogns.board_back.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.ImageEntity;
import jakarta.transaction.Transactional;
import java.util.List;
@Repository
public interface ImageRepository extends JpaRepository<ImageEntity, Integer>{
List<ImageEntity> findByBoardNumber(Integer boardNumber);
@Transactional
void deleteByBoardNumber(Integer boardNumber);
}

View File

@ -0,0 +1,11 @@
package com.eogns.board_back.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.SearchLogEntity;
@Repository
public interface SearchLogRepository extends JpaRepository<SearchLogEntity, Integer>{
}

View File

@ -0,0 +1,16 @@
package com.eogns.board_back.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.eogns.board_back.entity.UserEntity;
@Repository
public interface UserRepository extends JpaRepository<UserEntity, String>{
boolean existsByEmail(String email);
boolean existsByNickname(String nickname);
boolean existsByTelNumber(String telNumber);
UserEntity findByEmail(String email);
}

Some files were not shown because too many files have changed in this diff Show More