├── auth-server ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── authserver │ │ │ ├── AuthServerApplication.java │ │ │ └── config │ │ │ ├── AuthorizationServerConfig.java │ │ │ ├── CORSCustomizer.java │ │ │ ├── WebSecurityConfig.java │ │ │ └── keys │ │ │ └── JwksKeys.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── example │ └── authserver │ └── AuthServerApplicationTests.java ├── node_modules ├── base64-js │ ├── LICENSE │ ├── README.md │ ├── base64js.min.js │ ├── index.d.ts │ ├── index.js │ └── package.json ├── buffer │ ├── AUTHORS.md │ ├── LICENSE │ ├── README.md │ ├── index.d.ts │ ├── index.js │ └── package.json └── ieee754 │ ├── LICENSE │ ├── README.md │ ├── index.d.ts │ ├── index.js │ └── package.json ├── oauth2_angular ├── .browserslistrc ├── .editorconfig ├── .gitignore ├── .vscode │ ├── extensions.json │ ├── launch.json │ └── tasks.json ├── README.md ├── angular.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── app.routes.ts │ │ ├── auth │ │ │ ├── auth.component.css │ │ │ ├── auth.component.html │ │ │ ├── auth.component.spec.ts │ │ │ └── auth.component.ts │ │ ├── constants │ │ │ ├── demo.ts │ │ │ ├── redirect.ts │ │ │ └── token.ts │ │ ├── home │ │ │ ├── home.component.css │ │ │ ├── home.component.html │ │ │ ├── home.component.spec.ts │ │ │ └── home.component.ts │ │ ├── login │ │ │ ├── login.component.css │ │ │ ├── login.component.html │ │ │ ├── login.component.spec.ts │ │ │ └── login.component.ts │ │ └── services │ │ │ ├── auth.service.ts │ │ │ └── http.service.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json ├── oauth2_react ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Home.js │ ├── Login.js │ └── Redirect.js │ ├── index.css │ ├── index.js │ ├── links │ └── demo.js │ ├── logo.svg │ ├── pkce │ └── pkce.js │ ├── reportWebVitals.js │ └── setupTests.js ├── package-lock.json └── resource-server ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── example │ │ └── resourceserver │ │ ├── ResourceServerApplication.java │ │ ├── config │ │ └── SecurityConfig.java │ │ └── controllers │ │ └── DemoController.java └── resources │ └── application.properties └── test └── java └── com └── example └── resourceserver └── ResourceServerApplicationTests.java /auth-server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /auth-server/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/auth-server/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /auth-server/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /auth-server/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /auth-server/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /auth-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.0.1 9 | 10 | 11 | com.example 12 | auth-server 13 | 0.0.1-SNAPSHOT 14 | auth-server 15 | auth-server 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-security 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | org.springframework.security 30 | spring-security-oauth2-authorization-server 31 | 1.0.0 32 | 33 | 34 | org.projectlombok 35 | lombok 36 | true 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.springframework.security 45 | spring-security-test 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | org.projectlombok 59 | lombok 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /auth-server/src/main/java/com/example/authserver/AuthServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class AuthServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(AuthServerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /auth-server/src/main/java/com/example/authserver/config/AuthorizationServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver.config; 2 | 3 | import com.example.authserver.config.keys.JwksKeys; 4 | import com.nimbusds.jose.jwk.JWKSet; 5 | import com.nimbusds.jose.jwk.RSAKey; 6 | import com.nimbusds.jose.jwk.source.JWKSource; 7 | import com.nimbusds.jose.proc.SecurityContext; 8 | import lombok.AllArgsConstructor; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.Ordered; 12 | import org.springframework.core.annotation.Order; 13 | import org.springframework.security.config.Customizer; 14 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 15 | import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; 16 | import org.springframework.security.oauth2.core.AuthorizationGrantType; 17 | import org.springframework.security.oauth2.core.ClientAuthenticationMethod; 18 | import org.springframework.security.oauth2.core.oidc.OidcScopes; 19 | import org.springframework.security.oauth2.jwt.JwtDecoder; 20 | import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; 21 | import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; 22 | import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 23 | import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; 24 | import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; 25 | import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; 26 | import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; 27 | import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; 28 | import org.springframework.security.web.SecurityFilterChain; 29 | import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; 30 | 31 | import java.time.Duration; 32 | import java.util.UUID; 33 | 34 | @Configuration 35 | @AllArgsConstructor 36 | public class AuthorizationServerConfig { 37 | 38 | // http://localhost:8080/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=http://127.0.0.1:3000/authorized&code_challenge=QYPAZ5NU8yvtlQ9erXrUYR-T5AGCjCF47vN-KsaI2A8&code_challenge_method=S256 39 | // http://localhost:8080/oauth2/token?client_id=client&redirect_uri=http://127.0.0.1:3000/authorized&grant_type=authorization_code&code=MJ5WmUiOAnVFHi9BS6PS5dqHvO56fHkQVqR8gUg-yOmpgohvsFmH4xU6lFcwwDN0nkAcYdldOROnhAhf0cDROu-PgSup94fx28geM4p08TSEZ_c9c9vkL_yy34WBfnyY&code_verifier=qPsH306-ZDDaOE8DFzVn05TkN3ZZoVmI_6x4LsVglQI 40 | 41 | private final CORSCustomizer corsCustomizer; 42 | 43 | @Bean 44 | @Order(Ordered.HIGHEST_PRECEDENCE) 45 | public SecurityFilterChain securityASFilterChain(HttpSecurity http) throws Exception { 46 | OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); 47 | http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); 48 | http.exceptionHandling(exceptions -> exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))) 49 | .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); 50 | corsCustomizer.corsCustomizer(http); 51 | return http.formLogin().and().build(); 52 | } 53 | 54 | @Bean 55 | public RegisteredClientRepository registeredClientRepository() { 56 | RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) 57 | .clientId("client") 58 | .clientSecret("secret") 59 | .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) 60 | .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) 61 | .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) 62 | .redirectUri("http://127.0.0.1:3000/authorized") 63 | .scope(OidcScopes.OPENID) 64 | .clientSettings(ClientSettings.builder() 65 | .requireAuthorizationConsent(true).build()) 66 | .tokenSettings(TokenSettings.builder() 67 | .refreshTokenTimeToLive(Duration.ofHours(10)) 68 | .build()) 69 | .build(); 70 | 71 | return new InMemoryRegisteredClientRepository(registeredClient); 72 | } 73 | 74 | @Bean 75 | public AuthorizationServerSettings authorizationServerSettings() { 76 | return AuthorizationServerSettings.builder().issuer("http://localhost:8080").build(); 77 | } 78 | 79 | @Bean 80 | public JWKSource jwkSource() { 81 | RSAKey rsaKey = JwksKeys.generateRSAKey(); 82 | JWKSet set = new JWKSet(rsaKey); 83 | return (j, sc) -> j.select(set); 84 | } 85 | 86 | @Bean 87 | public JwtDecoder jwtDecoder(JWKSource jwkSource) { 88 | return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /auth-server/src/main/java/com/example/authserver/config/CORSCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver.config; 2 | 3 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.CorsConfigurationSource; 7 | 8 | import java.util.List; 9 | 10 | @Component 11 | public class CORSCustomizer { 12 | 13 | public void corsCustomizer(HttpSecurity http) throws Exception { 14 | http.cors(c -> { 15 | CorsConfigurationSource source = s -> { 16 | CorsConfiguration cc = new CorsConfiguration(); 17 | cc.setAllowCredentials(true); 18 | cc.setAllowedOrigins(List.of("http://127.0.0.1:3000")); 19 | cc.setAllowedHeaders(List.of("*")); 20 | cc.setAllowedMethods(List.of("*")); 21 | return cc; 22 | }; 23 | 24 | c.configurationSource(source); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /auth-server/src/main/java/com/example/authserver/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver.config; 2 | 3 | import lombok.AllArgsConstructor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.core.userdetails.User; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.crypto.password.NoOpPasswordEncoder; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | import org.springframework.security.provisioning.InMemoryUserDetailsManager; 12 | import org.springframework.security.web.SecurityFilterChain; 13 | 14 | @Configuration 15 | @AllArgsConstructor 16 | public class WebSecurityConfig { 17 | 18 | private final CORSCustomizer corsCustomizer; 19 | 20 | @Bean 21 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 22 | corsCustomizer.corsCustomizer(http); 23 | return http.formLogin() 24 | .and() 25 | .authorizeHttpRequests() 26 | .anyRequest().authenticated() 27 | .and().build(); 28 | } 29 | 30 | @Bean 31 | public UserDetailsService userDetailsService() { 32 | var u1 = User.withUsername("bill").password("12345").authorities("read").build(); 33 | 34 | var uds = new InMemoryUserDetailsManager(); 35 | uds.createUser(u1); 36 | return uds; 37 | } 38 | 39 | @Bean 40 | public PasswordEncoder passwordEncoder() { 41 | return NoOpPasswordEncoder.getInstance(); // only for demonstrations 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /auth-server/src/main/java/com/example/authserver/config/keys/JwksKeys.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver.config.keys; 2 | 3 | import com.nimbusds.jose.jwk.RSAKey; 4 | 5 | import java.security.KeyPairGenerator; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.interfaces.RSAPrivateKey; 8 | import java.security.interfaces.RSAPublicKey; 9 | import java.util.UUID; 10 | 11 | public class JwksKeys { 12 | 13 | public static RSAKey generateRSAKey() { 14 | try { 15 | KeyPairGenerator g = KeyPairGenerator.getInstance("RSA"); 16 | g.initialize(2048); 17 | var keyPair = g.generateKeyPair(); 18 | 19 | RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); 20 | RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); 21 | 22 | return new RSAKey.Builder(rsaPublicKey).privateKey(rsaPrivateKey).keyID(UUID.randomUUID().toString()).build(); 23 | } catch (NoSuchAlgorithmException e) { 24 | throw new RuntimeException("Problem generating the keys"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /auth-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /auth-server/src/test/java/com/example/authserver/AuthServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.authserver; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class AuthServerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /node_modules/base64-js/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jameson Little 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /node_modules/base64-js/README.md: -------------------------------------------------------------------------------- 1 | base64-js 2 | ========= 3 | 4 | `base64-js` does basic base64 encoding/decoding in pure JS. 5 | 6 | [![build status](https://secure.travis-ci.org/beatgammit/base64-js.png)](http://travis-ci.org/beatgammit/base64-js) 7 | 8 | Many browsers already have base64 encoding/decoding functionality, but it is for text data, not all-purpose binary data. 9 | 10 | Sometimes encoding/decoding binary data in the browser is useful, and that is what this module does. 11 | 12 | ## install 13 | 14 | With [npm](https://npmjs.org) do: 15 | 16 | `npm install base64-js` and `var base64js = require('base64-js')` 17 | 18 | For use in web browsers do: 19 | 20 | `` 21 | 22 | [Get supported base64-js with the Tidelift Subscription](https://tidelift.com/subscription/pkg/npm-base64-js?utm_source=npm-base64-js&utm_medium=referral&utm_campaign=readme) 23 | 24 | ## methods 25 | 26 | `base64js` has three exposed functions, `byteLength`, `toByteArray` and `fromByteArray`, which both take a single argument. 27 | 28 | * `byteLength` - Takes a base64 string and returns length of byte array 29 | * `toByteArray` - Takes a base64 string and returns a byte array 30 | * `fromByteArray` - Takes a byte array and returns a base64 string 31 | 32 | ## license 33 | 34 | MIT 35 | -------------------------------------------------------------------------------- /node_modules/base64-js/base64js.min.js: -------------------------------------------------------------------------------- 1 | (function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?this:self:global:window,b.base64js=a()}})(function(){return function(){function b(d,e,g){function a(j,i){if(!e[j]){if(!d[j]){var f="function"==typeof require&&require;if(!i&&f)return f(j,!0);if(h)return h(j,!0);var c=new Error("Cannot find module '"+j+"'");throw c.code="MODULE_NOT_FOUND",c}var k=e[j]={exports:{}};d[j][0].call(k.exports,function(b){var c=d[j][1][b];return a(c||b)},k,k.exports,b,d,e,g)}return e[j].exports}for(var h="function"==typeof require&&require,c=0;c>16,j[k++]=255&b>>8,j[k++]=255&b;return 2===h&&(b=l[a.charCodeAt(c)]<<2|l[a.charCodeAt(c+1)]>>4,j[k++]=255&b),1===h&&(b=l[a.charCodeAt(c)]<<10|l[a.charCodeAt(c+1)]<<4|l[a.charCodeAt(c+2)]>>2,j[k++]=255&b>>8,j[k++]=255&b),j}function g(a){return k[63&a>>18]+k[63&a>>12]+k[63&a>>6]+k[63&a]}function h(a,b,c){for(var d,e=[],f=b;fj?j:g+f));return 1===d?(b=a[c-1],e.push(k[b>>2]+k[63&b<<4]+"==")):2===d&&(b=(a[c-2]<<8)+a[c-1],e.push(k[b>>10]+k[63&b>>4]+k[63&b<<2]+"=")),e.join("")}c.byteLength=function(a){var b=d(a),c=b[0],e=b[1];return 3*(c+e)/4-e},c.toByteArray=f,c.fromByteArray=j;for(var k=[],l=[],m="undefined"==typeof Uint8Array?Array:Uint8Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o=0,p=n.length;o 0) { 26 | throw new Error('Invalid string. Length must be a multiple of 4') 27 | } 28 | 29 | // Trim off extra bytes after placeholder bytes are found 30 | // See: https://github.com/beatgammit/base64-js/issues/42 31 | var validLen = b64.indexOf('=') 32 | if (validLen === -1) validLen = len 33 | 34 | var placeHoldersLen = validLen === len 35 | ? 0 36 | : 4 - (validLen % 4) 37 | 38 | return [validLen, placeHoldersLen] 39 | } 40 | 41 | // base64 is 4/3 + up to two characters of the original data 42 | function byteLength (b64) { 43 | var lens = getLens(b64) 44 | var validLen = lens[0] 45 | var placeHoldersLen = lens[1] 46 | return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen 47 | } 48 | 49 | function _byteLength (b64, validLen, placeHoldersLen) { 50 | return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen 51 | } 52 | 53 | function toByteArray (b64) { 54 | var tmp 55 | var lens = getLens(b64) 56 | var validLen = lens[0] 57 | var placeHoldersLen = lens[1] 58 | 59 | var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) 60 | 61 | var curByte = 0 62 | 63 | // if there are placeholders, only get up to the last complete 4 chars 64 | var len = placeHoldersLen > 0 65 | ? validLen - 4 66 | : validLen 67 | 68 | var i 69 | for (i = 0; i < len; i += 4) { 70 | tmp = 71 | (revLookup[b64.charCodeAt(i)] << 18) | 72 | (revLookup[b64.charCodeAt(i + 1)] << 12) | 73 | (revLookup[b64.charCodeAt(i + 2)] << 6) | 74 | revLookup[b64.charCodeAt(i + 3)] 75 | arr[curByte++] = (tmp >> 16) & 0xFF 76 | arr[curByte++] = (tmp >> 8) & 0xFF 77 | arr[curByte++] = tmp & 0xFF 78 | } 79 | 80 | if (placeHoldersLen === 2) { 81 | tmp = 82 | (revLookup[b64.charCodeAt(i)] << 2) | 83 | (revLookup[b64.charCodeAt(i + 1)] >> 4) 84 | arr[curByte++] = tmp & 0xFF 85 | } 86 | 87 | if (placeHoldersLen === 1) { 88 | tmp = 89 | (revLookup[b64.charCodeAt(i)] << 10) | 90 | (revLookup[b64.charCodeAt(i + 1)] << 4) | 91 | (revLookup[b64.charCodeAt(i + 2)] >> 2) 92 | arr[curByte++] = (tmp >> 8) & 0xFF 93 | arr[curByte++] = tmp & 0xFF 94 | } 95 | 96 | return arr 97 | } 98 | 99 | function tripletToBase64 (num) { 100 | return lookup[num >> 18 & 0x3F] + 101 | lookup[num >> 12 & 0x3F] + 102 | lookup[num >> 6 & 0x3F] + 103 | lookup[num & 0x3F] 104 | } 105 | 106 | function encodeChunk (uint8, start, end) { 107 | var tmp 108 | var output = [] 109 | for (var i = start; i < end; i += 3) { 110 | tmp = 111 | ((uint8[i] << 16) & 0xFF0000) + 112 | ((uint8[i + 1] << 8) & 0xFF00) + 113 | (uint8[i + 2] & 0xFF) 114 | output.push(tripletToBase64(tmp)) 115 | } 116 | return output.join('') 117 | } 118 | 119 | function fromByteArray (uint8) { 120 | var tmp 121 | var len = uint8.length 122 | var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes 123 | var parts = [] 124 | var maxChunkLength = 16383 // must be multiple of 3 125 | 126 | // go through the array every three bytes, we'll deal with trailing stuff later 127 | for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { 128 | parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) 129 | } 130 | 131 | // pad the end with zeros, but make sure to not forget the extra bytes 132 | if (extraBytes === 1) { 133 | tmp = uint8[len - 1] 134 | parts.push( 135 | lookup[tmp >> 2] + 136 | lookup[(tmp << 4) & 0x3F] + 137 | '==' 138 | ) 139 | } else if (extraBytes === 2) { 140 | tmp = (uint8[len - 2] << 8) + uint8[len - 1] 141 | parts.push( 142 | lookup[tmp >> 10] + 143 | lookup[(tmp >> 4) & 0x3F] + 144 | lookup[(tmp << 2) & 0x3F] + 145 | '=' 146 | ) 147 | } 148 | 149 | return parts.join('') 150 | } 151 | -------------------------------------------------------------------------------- /node_modules/base64-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "base64-js@^1.3.1", 3 | "_id": "base64-js@1.5.1", 4 | "_inBundle": false, 5 | "_integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 6 | "_location": "/base64-js", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "base64-js@^1.3.1", 12 | "name": "base64-js", 13 | "escapedName": "base64-js", 14 | "rawSpec": "^1.3.1", 15 | "saveSpec": null, 16 | "fetchSpec": "^1.3.1" 17 | }, 18 | "_requiredBy": [ 19 | "/buffer" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 22 | "_shasum": "1b1b440160a5bf7ad40b650f095963481903930a", 23 | "_spec": "base64-js@^1.3.1", 24 | "_where": "C:\\full_stack_oauth2\\node_modules\\buffer", 25 | "author": { 26 | "name": "T. Jameson Little", 27 | "email": "t.jameson.little@gmail.com" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/beatgammit/base64-js/issues" 31 | }, 32 | "bundleDependencies": false, 33 | "deprecated": false, 34 | "description": "Base64 encoding/decoding in pure JS", 35 | "devDependencies": { 36 | "babel-minify": "^0.5.1", 37 | "benchmark": "^2.1.4", 38 | "browserify": "^16.3.0", 39 | "standard": "*", 40 | "tape": "4.x" 41 | }, 42 | "funding": [ 43 | { 44 | "type": "github", 45 | "url": "https://github.com/sponsors/feross" 46 | }, 47 | { 48 | "type": "patreon", 49 | "url": "https://www.patreon.com/feross" 50 | }, 51 | { 52 | "type": "consulting", 53 | "url": "https://feross.org/support" 54 | } 55 | ], 56 | "homepage": "https://github.com/beatgammit/base64-js", 57 | "keywords": [ 58 | "base64" 59 | ], 60 | "license": "MIT", 61 | "main": "index.js", 62 | "name": "base64-js", 63 | "repository": { 64 | "type": "git", 65 | "url": "git://github.com/beatgammit/base64-js.git" 66 | }, 67 | "scripts": { 68 | "build": "browserify -s base64js -r ./ | minify > base64js.min.js", 69 | "lint": "standard", 70 | "test": "npm run lint && npm run unit", 71 | "unit": "tape test/*.js" 72 | }, 73 | "typings": "index.d.ts", 74 | "version": "1.5.1" 75 | } 76 | -------------------------------------------------------------------------------- /node_modules/buffer/AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | #### Ordered by first contribution. 4 | 5 | - Romain Beauxis (toots@rastageeks.org) 6 | - Tobias Koppers (tobias.koppers@googlemail.com) 7 | - Janus (ysangkok@gmail.com) 8 | - Rainer Dreyer (rdrey1@gmail.com) 9 | - Tõnis Tiigi (tonistiigi@gmail.com) 10 | - James Halliday (mail@substack.net) 11 | - Michael Williamson (mike@zwobble.org) 12 | - elliottcable (github@elliottcable.name) 13 | - rafael (rvalle@livelens.net) 14 | - Andrew Kelley (superjoe30@gmail.com) 15 | - Andreas Madsen (amwebdk@gmail.com) 16 | - Mike Brevoort (mike.brevoort@pearson.com) 17 | - Brian White (mscdex@mscdex.net) 18 | - Feross Aboukhadijeh (feross@feross.org) 19 | - Ruben Verborgh (ruben@verborgh.org) 20 | - eliang (eliang.cs@gmail.com) 21 | - Jesse Tane (jesse.tane@gmail.com) 22 | - Alfonso Boza (alfonso@cloud.com) 23 | - Mathias Buus (mathiasbuus@gmail.com) 24 | - Devon Govett (devongovett@gmail.com) 25 | - Daniel Cousens (github@dcousens.com) 26 | - Joseph Dykstra (josephdykstra@gmail.com) 27 | - Parsha Pourkhomami (parshap+git@gmail.com) 28 | - Damjan Košir (damjan.kosir@gmail.com) 29 | - daverayment (dave.rayment@gmail.com) 30 | - kawanet (u-suke@kawa.net) 31 | - Linus Unnebäck (linus@folkdatorn.se) 32 | - Nolan Lawson (nolan.lawson@gmail.com) 33 | - Calvin Metcalf (calvin.metcalf@gmail.com) 34 | - Koki Takahashi (hakatasiloving@gmail.com) 35 | - Guy Bedford (guybedford@gmail.com) 36 | - Jan Schär (jscissr@gmail.com) 37 | - RaulTsc (tomescu.raul@gmail.com) 38 | - Matthieu Monsch (monsch@alum.mit.edu) 39 | - Dan Ehrenberg (littledan@chromium.org) 40 | - Kirill Fomichev (fanatid@ya.ru) 41 | - Yusuke Kawasaki (u-suke@kawa.net) 42 | - DC (dcposch@dcpos.ch) 43 | - John-David Dalton (john.david.dalton@gmail.com) 44 | - adventure-yunfei (adventure030@gmail.com) 45 | - Emil Bay (github@tixz.dk) 46 | - Sam Sudar (sudar.sam@gmail.com) 47 | - Volker Mische (volker.mische@gmail.com) 48 | - David Walton (support@geekstocks.com) 49 | - Сковорода Никита Андреевич (chalkerx@gmail.com) 50 | - greenkeeper[bot] (greenkeeper[bot]@users.noreply.github.com) 51 | - ukstv (sergey.ukustov@machinomy.com) 52 | - Renée Kooi (renee@kooi.me) 53 | - ranbochen (ranbochen@qq.com) 54 | - Vladimir Borovik (bobahbdb@gmail.com) 55 | - greenkeeper[bot] (23040076+greenkeeper[bot]@users.noreply.github.com) 56 | - kumavis (aaron@kumavis.me) 57 | - Sergey Ukustov (sergey.ukustov@machinomy.com) 58 | - Fei Liu (liu.feiwood@gmail.com) 59 | - Blaine Bublitz (blaine.bublitz@gmail.com) 60 | - clement (clement@seald.io) 61 | - Koushik Dutta (koushd@gmail.com) 62 | - Jordan Harband (ljharb@gmail.com) 63 | - Niklas Mischkulnig (mischnic@users.noreply.github.com) 64 | - Nikolai Vavilov (vvnicholas@gmail.com) 65 | - Fedor Nezhivoi (gyzerok@users.noreply.github.com) 66 | - shuse2 (shus.toda@gmail.com) 67 | - Peter Newman (peternewman@users.noreply.github.com) 68 | - mathmakgakpak (44949126+mathmakgakpak@users.noreply.github.com) 69 | - jkkang (jkkang@smartauth.kr) 70 | - Deklan Webster (deklanw@gmail.com) 71 | - Martin Heidegger (martin.heidegger@gmail.com) 72 | 73 | #### Generated by bin/update-authors.sh. 74 | -------------------------------------------------------------------------------- /node_modules/buffer/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Feross Aboukhadijeh, and other contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /node_modules/buffer/README.md: -------------------------------------------------------------------------------- 1 | # buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] 2 | 3 | [travis-image]: https://img.shields.io/travis/feross/buffer/master.svg 4 | [travis-url]: https://travis-ci.org/feross/buffer 5 | [npm-image]: https://img.shields.io/npm/v/buffer.svg 6 | [npm-url]: https://npmjs.org/package/buffer 7 | [downloads-image]: https://img.shields.io/npm/dm/buffer.svg 8 | [downloads-url]: https://npmjs.org/package/buffer 9 | [standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg 10 | [standard-url]: https://standardjs.com 11 | 12 | #### The buffer module from [node.js](https://nodejs.org/), for the browser. 13 | 14 | [![saucelabs][saucelabs-image]][saucelabs-url] 15 | 16 | [saucelabs-image]: https://saucelabs.com/browser-matrix/buffer.svg 17 | [saucelabs-url]: https://saucelabs.com/u/buffer 18 | 19 | With [browserify](http://browserify.org), simply `require('buffer')` or use the `Buffer` global and you will get this module. 20 | 21 | The goal is to provide an API that is 100% identical to 22 | [node's Buffer API](https://nodejs.org/api/buffer.html). Read the 23 | [official docs](https://nodejs.org/api/buffer.html) for the full list of properties, 24 | instance methods, and class methods that are supported. 25 | 26 | ## features 27 | 28 | - Manipulate binary data like a boss, in all browsers! 29 | - Super fast. Backed by Typed Arrays (`Uint8Array`/`ArrayBuffer`, not `Object`) 30 | - Extremely small bundle size (**6.75KB minified + gzipped**, 51.9KB with comments) 31 | - Excellent browser support (Chrome, Firefox, Edge, Safari 11+, iOS 11+, Android, etc.) 32 | - Preserves Node API exactly, with one minor difference (see below) 33 | - Square-bracket `buf[4]` notation works! 34 | - Does not modify any browser prototypes or put anything on `window` 35 | - Comprehensive test suite (including all buffer tests from node.js core) 36 | 37 | ## install 38 | 39 | To use this module directly (without browserify), install it: 40 | 41 | ```bash 42 | npm install buffer 43 | ``` 44 | 45 | This module was previously called **native-buffer-browserify**, but please use **buffer** 46 | from now on. 47 | 48 | If you do not use a bundler, you can use the [standalone script](https://bundle.run/buffer). 49 | 50 | ## usage 51 | 52 | The module's API is identical to node's `Buffer` API. Read the 53 | [official docs](https://nodejs.org/api/buffer.html) for the full list of properties, 54 | instance methods, and class methods that are supported. 55 | 56 | As mentioned above, `require('buffer')` or use the `Buffer` global with 57 | [browserify](http://browserify.org) and this module will automatically be included 58 | in your bundle. Almost any npm module will work in the browser, even if it assumes that 59 | the node `Buffer` API will be available. 60 | 61 | To depend on this module explicitly (without browserify), require it like this: 62 | 63 | ```js 64 | var Buffer = require('buffer/').Buffer // note: the trailing slash is important! 65 | ``` 66 | 67 | To require this module explicitly, use `require('buffer/')` which tells the node.js module 68 | lookup algorithm (also used by browserify) to use the **npm module** named `buffer` 69 | instead of the **node.js core** module named `buffer`! 70 | 71 | 72 | ## how does it work? 73 | 74 | The Buffer constructor returns instances of `Uint8Array` that have their prototype 75 | changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of `Uint8Array`, 76 | so the returned instances will have all the node `Buffer` methods and the 77 | `Uint8Array` methods. Square bracket notation works as expected -- it returns a 78 | single octet. 79 | 80 | The `Uint8Array` prototype remains unmodified. 81 | 82 | 83 | ## tracking the latest node api 84 | 85 | This module tracks the Buffer API in the latest (unstable) version of node.js. The Buffer 86 | API is considered **stable** in the 87 | [node stability index](https://nodejs.org/docs/latest/api/documentation.html#documentation_stability_index), 88 | so it is unlikely that there will ever be breaking changes. 89 | Nonetheless, when/if the Buffer API changes in node, this module's API will change 90 | accordingly. 91 | 92 | ## related packages 93 | 94 | - [`buffer-reverse`](https://www.npmjs.com/package/buffer-reverse) - Reverse a buffer 95 | - [`buffer-xor`](https://www.npmjs.com/package/buffer-xor) - Bitwise xor a buffer 96 | - [`is-buffer`](https://www.npmjs.com/package/is-buffer) - Determine if an object is a Buffer without including the whole `Buffer` package 97 | 98 | ## conversion packages 99 | 100 | ### convert typed array to buffer 101 | 102 | Use [`typedarray-to-buffer`](https://www.npmjs.com/package/typedarray-to-buffer) to convert any kind of typed array to a `Buffer`. Does not perform a copy, so it's super fast. 103 | 104 | ### convert buffer to typed array 105 | 106 | `Buffer` is a subclass of `Uint8Array` (which is a typed array). So there is no need to explicitly convert to typed array. Just use the buffer as a `Uint8Array`. 107 | 108 | ### convert blob to buffer 109 | 110 | Use [`blob-to-buffer`](https://www.npmjs.com/package/blob-to-buffer) to convert a `Blob` to a `Buffer`. 111 | 112 | ### convert buffer to blob 113 | 114 | To convert a `Buffer` to a `Blob`, use the `Blob` constructor: 115 | 116 | ```js 117 | var blob = new Blob([ buffer ]) 118 | ``` 119 | 120 | Optionally, specify a mimetype: 121 | 122 | ```js 123 | var blob = new Blob([ buffer ], { type: 'text/html' }) 124 | ``` 125 | 126 | ### convert arraybuffer to buffer 127 | 128 | To convert an `ArrayBuffer` to a `Buffer`, use the `Buffer.from` function. Does not perform a copy, so it's super fast. 129 | 130 | ```js 131 | var buffer = Buffer.from(arrayBuffer) 132 | ``` 133 | 134 | ### convert buffer to arraybuffer 135 | 136 | To convert a `Buffer` to an `ArrayBuffer`, use the `.buffer` property (which is present on all `Uint8Array` objects): 137 | 138 | ```js 139 | var arrayBuffer = buffer.buffer.slice( 140 | buffer.byteOffset, buffer.byteOffset + buffer.byteLength 141 | ) 142 | ``` 143 | 144 | Alternatively, use the [`to-arraybuffer`](https://www.npmjs.com/package/to-arraybuffer) module. 145 | 146 | ## performance 147 | 148 | See perf tests in `/perf`. 149 | 150 | `BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as a 151 | sanity check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will 152 | always be at least a bit faster). Finally, `NodeBuffer` is the node.js buffer module, 153 | which is included to compare against. 154 | 155 | NOTE: Performance has improved since these benchmarks were taken. PR welcome to update the README. 156 | 157 | ### Chrome 38 158 | 159 | | Method | Operations | Accuracy | Sampled | Fastest | 160 | |:-------|:-----------|:---------|:--------|:-------:| 161 | | BrowserBuffer#bracket-notation | 11,457,464 ops/sec | ±0.86% | 66 | ✓ | 162 | | Uint8Array#bracket-notation | 10,824,332 ops/sec | ±0.74% | 65 | | 163 | | | | | | 164 | | BrowserBuffer#concat | 450,532 ops/sec | ±0.76% | 68 | | 165 | | Uint8Array#concat | 1,368,911 ops/sec | ±1.50% | 62 | ✓ | 166 | | | | | | 167 | | BrowserBuffer#copy(16000) | 903,001 ops/sec | ±0.96% | 67 | | 168 | | Uint8Array#copy(16000) | 1,422,441 ops/sec | ±1.04% | 66 | ✓ | 169 | | | | | | 170 | | BrowserBuffer#copy(16) | 11,431,358 ops/sec | ±0.46% | 69 | | 171 | | Uint8Array#copy(16) | 13,944,163 ops/sec | ±1.12% | 68 | ✓ | 172 | | | | | | 173 | | BrowserBuffer#new(16000) | 106,329 ops/sec | ±6.70% | 44 | | 174 | | Uint8Array#new(16000) | 131,001 ops/sec | ±2.85% | 31 | ✓ | 175 | | | | | | 176 | | BrowserBuffer#new(16) | 1,554,491 ops/sec | ±1.60% | 65 | | 177 | | Uint8Array#new(16) | 6,623,930 ops/sec | ±1.66% | 65 | ✓ | 178 | | | | | | 179 | | BrowserBuffer#readDoubleBE | 112,830 ops/sec | ±0.51% | 69 | ✓ | 180 | | DataView#getFloat64 | 93,500 ops/sec | ±0.57% | 68 | | 181 | | | | | | 182 | | BrowserBuffer#readFloatBE | 146,678 ops/sec | ±0.95% | 68 | ✓ | 183 | | DataView#getFloat32 | 99,311 ops/sec | ±0.41% | 67 | | 184 | | | | | | 185 | | BrowserBuffer#readUInt32LE | 843,214 ops/sec | ±0.70% | 69 | ✓ | 186 | | DataView#getUint32 | 103,024 ops/sec | ±0.64% | 67 | | 187 | | | | | | 188 | | BrowserBuffer#slice | 1,013,941 ops/sec | ±0.75% | 67 | | 189 | | Uint8Array#subarray | 1,903,928 ops/sec | ±0.53% | 67 | ✓ | 190 | | | | | | 191 | | BrowserBuffer#writeFloatBE | 61,387 ops/sec | ±0.90% | 67 | | 192 | | DataView#setFloat32 | 141,249 ops/sec | ±0.40% | 66 | ✓ | 193 | 194 | 195 | ### Firefox 33 196 | 197 | | Method | Operations | Accuracy | Sampled | Fastest | 198 | |:-------|:-----------|:---------|:--------|:-------:| 199 | | BrowserBuffer#bracket-notation | 20,800,421 ops/sec | ±1.84% | 60 | | 200 | | Uint8Array#bracket-notation | 20,826,235 ops/sec | ±2.02% | 61 | ✓ | 201 | | | | | | 202 | | BrowserBuffer#concat | 153,076 ops/sec | ±2.32% | 61 | | 203 | | Uint8Array#concat | 1,255,674 ops/sec | ±8.65% | 52 | ✓ | 204 | | | | | | 205 | | BrowserBuffer#copy(16000) | 1,105,312 ops/sec | ±1.16% | 63 | | 206 | | Uint8Array#copy(16000) | 1,615,911 ops/sec | ±0.55% | 66 | ✓ | 207 | | | | | | 208 | | BrowserBuffer#copy(16) | 16,357,599 ops/sec | ±0.73% | 68 | | 209 | | Uint8Array#copy(16) | 31,436,281 ops/sec | ±1.05% | 68 | ✓ | 210 | | | | | | 211 | | BrowserBuffer#new(16000) | 52,995 ops/sec | ±6.01% | 35 | | 212 | | Uint8Array#new(16000) | 87,686 ops/sec | ±5.68% | 45 | ✓ | 213 | | | | | | 214 | | BrowserBuffer#new(16) | 252,031 ops/sec | ±1.61% | 66 | | 215 | | Uint8Array#new(16) | 8,477,026 ops/sec | ±0.49% | 68 | ✓ | 216 | | | | | | 217 | | BrowserBuffer#readDoubleBE | 99,871 ops/sec | ±0.41% | 69 | | 218 | | DataView#getFloat64 | 285,663 ops/sec | ±0.70% | 68 | ✓ | 219 | | | | | | 220 | | BrowserBuffer#readFloatBE | 115,540 ops/sec | ±0.42% | 69 | | 221 | | DataView#getFloat32 | 288,722 ops/sec | ±0.82% | 68 | ✓ | 222 | | | | | | 223 | | BrowserBuffer#readUInt32LE | 633,926 ops/sec | ±1.08% | 67 | ✓ | 224 | | DataView#getUint32 | 294,808 ops/sec | ±0.79% | 64 | | 225 | | | | | | 226 | | BrowserBuffer#slice | 349,425 ops/sec | ±0.46% | 69 | | 227 | | Uint8Array#subarray | 5,965,819 ops/sec | ±0.60% | 65 | ✓ | 228 | | | | | | 229 | | BrowserBuffer#writeFloatBE | 59,980 ops/sec | ±0.41% | 67 | | 230 | | DataView#setFloat32 | 317,634 ops/sec | ±0.63% | 68 | ✓ | 231 | 232 | ### Safari 8 233 | 234 | | Method | Operations | Accuracy | Sampled | Fastest | 235 | |:-------|:-----------|:---------|:--------|:-------:| 236 | | BrowserBuffer#bracket-notation | 10,279,729 ops/sec | ±2.25% | 56 | ✓ | 237 | | Uint8Array#bracket-notation | 10,030,767 ops/sec | ±2.23% | 59 | | 238 | | | | | | 239 | | BrowserBuffer#concat | 144,138 ops/sec | ±1.38% | 65 | | 240 | | Uint8Array#concat | 4,950,764 ops/sec | ±1.70% | 63 | ✓ | 241 | | | | | | 242 | | BrowserBuffer#copy(16000) | 1,058,548 ops/sec | ±1.51% | 64 | | 243 | | Uint8Array#copy(16000) | 1,409,666 ops/sec | ±1.17% | 65 | ✓ | 244 | | | | | | 245 | | BrowserBuffer#copy(16) | 6,282,529 ops/sec | ±1.88% | 58 | | 246 | | Uint8Array#copy(16) | 11,907,128 ops/sec | ±2.87% | 58 | ✓ | 247 | | | | | | 248 | | BrowserBuffer#new(16000) | 101,663 ops/sec | ±3.89% | 57 | | 249 | | Uint8Array#new(16000) | 22,050,818 ops/sec | ±6.51% | 46 | ✓ | 250 | | | | | | 251 | | BrowserBuffer#new(16) | 176,072 ops/sec | ±2.13% | 64 | | 252 | | Uint8Array#new(16) | 24,385,731 ops/sec | ±5.01% | 51 | ✓ | 253 | | | | | | 254 | | BrowserBuffer#readDoubleBE | 41,341 ops/sec | ±1.06% | 67 | | 255 | | DataView#getFloat64 | 322,280 ops/sec | ±0.84% | 68 | ✓ | 256 | | | | | | 257 | | BrowserBuffer#readFloatBE | 46,141 ops/sec | ±1.06% | 65 | | 258 | | DataView#getFloat32 | 337,025 ops/sec | ±0.43% | 69 | ✓ | 259 | | | | | | 260 | | BrowserBuffer#readUInt32LE | 151,551 ops/sec | ±1.02% | 66 | | 261 | | DataView#getUint32 | 308,278 ops/sec | ±0.94% | 67 | ✓ | 262 | | | | | | 263 | | BrowserBuffer#slice | 197,365 ops/sec | ±0.95% | 66 | | 264 | | Uint8Array#subarray | 9,558,024 ops/sec | ±3.08% | 58 | ✓ | 265 | | | | | | 266 | | BrowserBuffer#writeFloatBE | 17,518 ops/sec | ±1.03% | 63 | | 267 | | DataView#setFloat32 | 319,751 ops/sec | ±0.48% | 68 | ✓ | 268 | 269 | 270 | ### Node 0.11.14 271 | 272 | | Method | Operations | Accuracy | Sampled | Fastest | 273 | |:-------|:-----------|:---------|:--------|:-------:| 274 | | BrowserBuffer#bracket-notation | 10,489,828 ops/sec | ±3.25% | 90 | | 275 | | Uint8Array#bracket-notation | 10,534,884 ops/sec | ±0.81% | 92 | ✓ | 276 | | NodeBuffer#bracket-notation | 10,389,910 ops/sec | ±0.97% | 87 | | 277 | | | | | | 278 | | BrowserBuffer#concat | 487,830 ops/sec | ±2.58% | 88 | | 279 | | Uint8Array#concat | 1,814,327 ops/sec | ±1.28% | 88 | ✓ | 280 | | NodeBuffer#concat | 1,636,523 ops/sec | ±1.88% | 73 | | 281 | | | | | | 282 | | BrowserBuffer#copy(16000) | 1,073,665 ops/sec | ±0.77% | 90 | | 283 | | Uint8Array#copy(16000) | 1,348,517 ops/sec | ±0.84% | 89 | ✓ | 284 | | NodeBuffer#copy(16000) | 1,289,533 ops/sec | ±0.82% | 93 | | 285 | | | | | | 286 | | BrowserBuffer#copy(16) | 12,782,706 ops/sec | ±0.74% | 85 | | 287 | | Uint8Array#copy(16) | 14,180,427 ops/sec | ±0.93% | 92 | ✓ | 288 | | NodeBuffer#copy(16) | 11,083,134 ops/sec | ±1.06% | 89 | | 289 | | | | | | 290 | | BrowserBuffer#new(16000) | 141,678 ops/sec | ±3.30% | 67 | | 291 | | Uint8Array#new(16000) | 161,491 ops/sec | ±2.96% | 60 | | 292 | | NodeBuffer#new(16000) | 292,699 ops/sec | ±3.20% | 55 | ✓ | 293 | | | | | | 294 | | BrowserBuffer#new(16) | 1,655,466 ops/sec | ±2.41% | 82 | | 295 | | Uint8Array#new(16) | 14,399,926 ops/sec | ±0.91% | 94 | ✓ | 296 | | NodeBuffer#new(16) | 3,894,696 ops/sec | ±0.88% | 92 | | 297 | | | | | | 298 | | BrowserBuffer#readDoubleBE | 109,582 ops/sec | ±0.75% | 93 | ✓ | 299 | | DataView#getFloat64 | 91,235 ops/sec | ±0.81% | 90 | | 300 | | NodeBuffer#readDoubleBE | 88,593 ops/sec | ±0.96% | 81 | | 301 | | | | | | 302 | | BrowserBuffer#readFloatBE | 139,854 ops/sec | ±1.03% | 85 | ✓ | 303 | | DataView#getFloat32 | 98,744 ops/sec | ±0.80% | 89 | | 304 | | NodeBuffer#readFloatBE | 92,769 ops/sec | ±0.94% | 93 | | 305 | | | | | | 306 | | BrowserBuffer#readUInt32LE | 710,861 ops/sec | ±0.82% | 92 | | 307 | | DataView#getUint32 | 117,893 ops/sec | ±0.84% | 91 | | 308 | | NodeBuffer#readUInt32LE | 851,412 ops/sec | ±0.72% | 93 | ✓ | 309 | | | | | | 310 | | BrowserBuffer#slice | 1,673,877 ops/sec | ±0.73% | 94 | | 311 | | Uint8Array#subarray | 6,919,243 ops/sec | ±0.67% | 90 | ✓ | 312 | | NodeBuffer#slice | 4,617,604 ops/sec | ±0.79% | 93 | | 313 | | | | | | 314 | | BrowserBuffer#writeFloatBE | 66,011 ops/sec | ±0.75% | 93 | | 315 | | DataView#setFloat32 | 127,760 ops/sec | ±0.72% | 93 | ✓ | 316 | | NodeBuffer#writeFloatBE | 103,352 ops/sec | ±0.83% | 93 | | 317 | 318 | ### iojs 1.8.1 319 | 320 | | Method | Operations | Accuracy | Sampled | Fastest | 321 | |:-------|:-----------|:---------|:--------|:-------:| 322 | | BrowserBuffer#bracket-notation | 10,990,488 ops/sec | ±1.11% | 91 | | 323 | | Uint8Array#bracket-notation | 11,268,757 ops/sec | ±0.65% | 97 | | 324 | | NodeBuffer#bracket-notation | 11,353,260 ops/sec | ±0.83% | 94 | ✓ | 325 | | | | | | 326 | | BrowserBuffer#concat | 378,954 ops/sec | ±0.74% | 94 | | 327 | | Uint8Array#concat | 1,358,288 ops/sec | ±0.97% | 87 | | 328 | | NodeBuffer#concat | 1,934,050 ops/sec | ±1.11% | 78 | ✓ | 329 | | | | | | 330 | | BrowserBuffer#copy(16000) | 894,538 ops/sec | ±0.56% | 84 | | 331 | | Uint8Array#copy(16000) | 1,442,656 ops/sec | ±0.71% | 96 | | 332 | | NodeBuffer#copy(16000) | 1,457,898 ops/sec | ±0.53% | 92 | ✓ | 333 | | | | | | 334 | | BrowserBuffer#copy(16) | 12,870,457 ops/sec | ±0.67% | 95 | | 335 | | Uint8Array#copy(16) | 16,643,989 ops/sec | ±0.61% | 93 | ✓ | 336 | | NodeBuffer#copy(16) | 14,885,848 ops/sec | ±0.74% | 94 | | 337 | | | | | | 338 | | BrowserBuffer#new(16000) | 109,264 ops/sec | ±4.21% | 63 | | 339 | | Uint8Array#new(16000) | 138,916 ops/sec | ±1.87% | 61 | | 340 | | NodeBuffer#new(16000) | 281,449 ops/sec | ±3.58% | 51 | ✓ | 341 | | | | | | 342 | | BrowserBuffer#new(16) | 1,362,935 ops/sec | ±0.56% | 99 | | 343 | | Uint8Array#new(16) | 6,193,090 ops/sec | ±0.64% | 95 | ✓ | 344 | | NodeBuffer#new(16) | 4,745,425 ops/sec | ±1.56% | 90 | | 345 | | | | | | 346 | | BrowserBuffer#readDoubleBE | 118,127 ops/sec | ±0.59% | 93 | ✓ | 347 | | DataView#getFloat64 | 107,332 ops/sec | ±0.65% | 91 | | 348 | | NodeBuffer#readDoubleBE | 116,274 ops/sec | ±0.94% | 95 | | 349 | | | | | | 350 | | BrowserBuffer#readFloatBE | 150,326 ops/sec | ±0.58% | 95 | ✓ | 351 | | DataView#getFloat32 | 110,541 ops/sec | ±0.57% | 98 | | 352 | | NodeBuffer#readFloatBE | 121,599 ops/sec | ±0.60% | 87 | | 353 | | | | | | 354 | | BrowserBuffer#readUInt32LE | 814,147 ops/sec | ±0.62% | 93 | | 355 | | DataView#getUint32 | 137,592 ops/sec | ±0.64% | 90 | | 356 | | NodeBuffer#readUInt32LE | 931,650 ops/sec | ±0.71% | 96 | ✓ | 357 | | | | | | 358 | | BrowserBuffer#slice | 878,590 ops/sec | ±0.68% | 93 | | 359 | | Uint8Array#subarray | 2,843,308 ops/sec | ±1.02% | 90 | | 360 | | NodeBuffer#slice | 4,998,316 ops/sec | ±0.68% | 90 | ✓ | 361 | | | | | | 362 | | BrowserBuffer#writeFloatBE | 65,927 ops/sec | ±0.74% | 93 | | 363 | | DataView#setFloat32 | 139,823 ops/sec | ±0.97% | 89 | ✓ | 364 | | NodeBuffer#writeFloatBE | 135,763 ops/sec | ±0.65% | 96 | | 365 | | | | | | 366 | 367 | ## Testing the project 368 | 369 | First, install the project: 370 | 371 | npm install 372 | 373 | Then, to run tests in Node.js, run: 374 | 375 | npm run test-node 376 | 377 | To test locally in a browser, you can run: 378 | 379 | npm run test-browser-es5-local # For ES5 browsers that don't support ES6 380 | npm run test-browser-es6-local # For ES6 compliant browsers 381 | 382 | This will print out a URL that you can then open in a browser to run the tests, using [airtap](https://www.npmjs.com/package/airtap). 383 | 384 | To run automated browser tests using Saucelabs, ensure that your `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables are set, then run: 385 | 386 | npm test 387 | 388 | This is what's run in Travis, to check against various browsers. The list of browsers is kept in the `bin/airtap-es5.yml` and `bin/airtap-es6.yml` files. 389 | 390 | ## JavaScript Standard Style 391 | 392 | This module uses [JavaScript Standard Style](https://github.com/feross/standard). 393 | 394 | [![JavaScript Style Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) 395 | 396 | To test that the code conforms to the style, `npm install` and run: 397 | 398 | ./node_modules/.bin/standard 399 | 400 | ## credit 401 | 402 | This was originally forked from [buffer-browserify](https://github.com/toots/buffer-browserify). 403 | 404 | ## Security Policies and Procedures 405 | 406 | The `buffer` team and community take all security bugs in `buffer` seriously. Please see our [security policies and procedures](https://github.com/feross/security) document to learn how to report issues. 407 | 408 | ## license 409 | 410 | MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org), and other contributors. Originally forked from an MIT-licensed module by Romain Beauxis. 411 | -------------------------------------------------------------------------------- /node_modules/buffer/index.d.ts: -------------------------------------------------------------------------------- 1 | export class Buffer extends Uint8Array { 2 | length: number 3 | write(string: string, offset?: number, length?: number, encoding?: string): number; 4 | toString(encoding?: string, start?: number, end?: number): string; 5 | toJSON(): { type: 'Buffer', data: any[] }; 6 | equals(otherBuffer: Buffer): boolean; 7 | compare(otherBuffer: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; 8 | copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; 9 | slice(start?: number, end?: number): Buffer; 10 | writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; 11 | writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; 12 | writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; 13 | writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; 14 | readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; 15 | readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; 16 | readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; 17 | readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; 18 | readUInt8(offset: number, noAssert?: boolean): number; 19 | readUInt16LE(offset: number, noAssert?: boolean): number; 20 | readUInt16BE(offset: number, noAssert?: boolean): number; 21 | readUInt32LE(offset: number, noAssert?: boolean): number; 22 | readUInt32BE(offset: number, noAssert?: boolean): number; 23 | readBigUInt64LE(offset: number): BigInt; 24 | readBigUInt64BE(offset: number): BigInt; 25 | readInt8(offset: number, noAssert?: boolean): number; 26 | readInt16LE(offset: number, noAssert?: boolean): number; 27 | readInt16BE(offset: number, noAssert?: boolean): number; 28 | readInt32LE(offset: number, noAssert?: boolean): number; 29 | readInt32BE(offset: number, noAssert?: boolean): number; 30 | readBigInt64LE(offset: number): BigInt; 31 | readBigInt64BE(offset: number): BigInt; 32 | readFloatLE(offset: number, noAssert?: boolean): number; 33 | readFloatBE(offset: number, noAssert?: boolean): number; 34 | readDoubleLE(offset: number, noAssert?: boolean): number; 35 | readDoubleBE(offset: number, noAssert?: boolean): number; 36 | reverse(): this; 37 | swap16(): Buffer; 38 | swap32(): Buffer; 39 | swap64(): Buffer; 40 | writeUInt8(value: number, offset: number, noAssert?: boolean): number; 41 | writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; 42 | writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; 43 | writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; 44 | writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; 45 | writeBigUInt64LE(value: number, offset: number): BigInt; 46 | writeBigUInt64BE(value: number, offset: number): BigInt; 47 | writeInt8(value: number, offset: number, noAssert?: boolean): number; 48 | writeInt16LE(value: number, offset: number, noAssert?: boolean): number; 49 | writeInt16BE(value: number, offset: number, noAssert?: boolean): number; 50 | writeInt32LE(value: number, offset: number, noAssert?: boolean): number; 51 | writeInt32BE(value: number, offset: number, noAssert?: boolean): number; 52 | writeBigInt64LE(value: number, offset: number): BigInt; 53 | writeBigInt64BE(value: number, offset: number): BigInt; 54 | writeFloatLE(value: number, offset: number, noAssert?: boolean): number; 55 | writeFloatBE(value: number, offset: number, noAssert?: boolean): number; 56 | writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; 57 | writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; 58 | fill(value: any, offset?: number, end?: number): this; 59 | indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; 60 | lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; 61 | includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; 62 | 63 | /** 64 | * Allocates a new buffer containing the given {str}. 65 | * 66 | * @param str String to store in buffer. 67 | * @param encoding encoding to use, optional. Default is 'utf8' 68 | */ 69 | constructor (str: string, encoding?: string); 70 | /** 71 | * Allocates a new buffer of {size} octets. 72 | * 73 | * @param size count of octets to allocate. 74 | */ 75 | constructor (size: number); 76 | /** 77 | * Allocates a new buffer containing the given {array} of octets. 78 | * 79 | * @param array The octets to store. 80 | */ 81 | constructor (array: Uint8Array); 82 | /** 83 | * Produces a Buffer backed by the same allocated memory as 84 | * the given {ArrayBuffer}. 85 | * 86 | * 87 | * @param arrayBuffer The ArrayBuffer with which to share memory. 88 | */ 89 | constructor (arrayBuffer: ArrayBuffer); 90 | /** 91 | * Allocates a new buffer containing the given {array} of octets. 92 | * 93 | * @param array The octets to store. 94 | */ 95 | constructor (array: any[]); 96 | /** 97 | * Copies the passed {buffer} data onto a new {Buffer} instance. 98 | * 99 | * @param buffer The buffer to copy. 100 | */ 101 | constructor (buffer: Buffer); 102 | prototype: Buffer; 103 | /** 104 | * Allocates a new Buffer using an {array} of octets. 105 | * 106 | * @param array 107 | */ 108 | static from(array: any[]): Buffer; 109 | /** 110 | * When passed a reference to the .buffer property of a TypedArray instance, 111 | * the newly created Buffer will share the same allocated memory as the TypedArray. 112 | * The optional {byteOffset} and {length} arguments specify a memory range 113 | * within the {arrayBuffer} that will be shared by the Buffer. 114 | * 115 | * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() 116 | * @param byteOffset 117 | * @param length 118 | */ 119 | static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; 120 | /** 121 | * Copies the passed {buffer} data onto a new Buffer instance. 122 | * 123 | * @param buffer 124 | */ 125 | static from(buffer: Buffer | Uint8Array): Buffer; 126 | /** 127 | * Creates a new Buffer containing the given JavaScript string {str}. 128 | * If provided, the {encoding} parameter identifies the character encoding. 129 | * If not provided, {encoding} defaults to 'utf8'. 130 | * 131 | * @param str 132 | */ 133 | static from(str: string, encoding?: string): Buffer; 134 | /** 135 | * Returns true if {obj} is a Buffer 136 | * 137 | * @param obj object to test. 138 | */ 139 | static isBuffer(obj: any): obj is Buffer; 140 | /** 141 | * Returns true if {encoding} is a valid encoding argument. 142 | * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' 143 | * 144 | * @param encoding string to test. 145 | */ 146 | static isEncoding(encoding: string): boolean; 147 | /** 148 | * Gives the actual byte length of a string. encoding defaults to 'utf8'. 149 | * This is not the same as String.prototype.length since that returns the number of characters in a string. 150 | * 151 | * @param string string to test. 152 | * @param encoding encoding used to evaluate (defaults to 'utf8') 153 | */ 154 | static byteLength(string: string, encoding?: string): number; 155 | /** 156 | * Returns a buffer which is the result of concatenating all the buffers in the list together. 157 | * 158 | * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. 159 | * If the list has exactly one item, then the first item of the list is returned. 160 | * If the list has more than one item, then a new Buffer is created. 161 | * 162 | * @param list An array of Buffer objects to concatenate 163 | * @param totalLength Total length of the buffers when concatenated. 164 | * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. 165 | */ 166 | static concat(list: Uint8Array[], totalLength?: number): Buffer; 167 | /** 168 | * The same as buf1.compare(buf2). 169 | */ 170 | static compare(buf1: Uint8Array, buf2: Uint8Array): number; 171 | /** 172 | * Allocates a new buffer of {size} octets. 173 | * 174 | * @param size count of octets to allocate. 175 | * @param fill if specified, buffer will be initialized by calling buf.fill(fill). 176 | * If parameter is omitted, buffer will be filled with zeros. 177 | * @param encoding encoding used for call to buf.fill while initializing 178 | */ 179 | static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; 180 | /** 181 | * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents 182 | * of the newly created Buffer are unknown and may contain sensitive data. 183 | * 184 | * @param size count of octets to allocate 185 | */ 186 | static allocUnsafe(size: number): Buffer; 187 | /** 188 | * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents 189 | * of the newly created Buffer are unknown and may contain sensitive data. 190 | * 191 | * @param size count of octets to allocate 192 | */ 193 | static allocUnsafeSlow(size: number): Buffer; 194 | } 195 | -------------------------------------------------------------------------------- /node_modules/buffer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "buffer", 3 | "_id": "buffer@6.0.3", 4 | "_inBundle": false, 5 | "_integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 6 | "_location": "/buffer", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "buffer", 12 | "name": "buffer", 13 | "escapedName": "buffer", 14 | "rawSpec": "", 15 | "saveSpec": null, 16 | "fetchSpec": "latest" 17 | }, 18 | "_requiredBy": [ 19 | "#USER", 20 | "/" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 23 | "_shasum": "2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6", 24 | "_spec": "buffer", 25 | "_where": "C:\\full_stack_oauth2", 26 | "author": { 27 | "name": "Feross Aboukhadijeh", 28 | "email": "feross@feross.org", 29 | "url": "https://feross.org" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/feross/buffer/issues" 33 | }, 34 | "bundleDependencies": false, 35 | "contributors": [ 36 | { 37 | "name": "Romain Beauxis", 38 | "email": "toots@rastageeks.org" 39 | }, 40 | { 41 | "name": "James Halliday", 42 | "email": "mail@substack.net" 43 | } 44 | ], 45 | "dependencies": { 46 | "base64-js": "^1.3.1", 47 | "ieee754": "^1.2.1" 48 | }, 49 | "deprecated": false, 50 | "description": "Node.js Buffer API, for the browser", 51 | "devDependencies": { 52 | "airtap": "^3.0.0", 53 | "benchmark": "^2.1.4", 54 | "browserify": "^17.0.0", 55 | "concat-stream": "^2.0.0", 56 | "hyperquest": "^2.1.3", 57 | "is-buffer": "^2.0.5", 58 | "is-nan": "^1.3.0", 59 | "split": "^1.0.1", 60 | "standard": "*", 61 | "tape": "^5.0.1", 62 | "through2": "^4.0.2", 63 | "uglify-js": "^3.11.5" 64 | }, 65 | "funding": [ 66 | { 67 | "type": "github", 68 | "url": "https://github.com/sponsors/feross" 69 | }, 70 | { 71 | "type": "patreon", 72 | "url": "https://www.patreon.com/feross" 73 | }, 74 | { 75 | "type": "consulting", 76 | "url": "https://feross.org/support" 77 | } 78 | ], 79 | "homepage": "https://github.com/feross/buffer", 80 | "jspm": { 81 | "map": { 82 | "./index.js": { 83 | "node": "@node/buffer" 84 | } 85 | } 86 | }, 87 | "keywords": [ 88 | "arraybuffer", 89 | "browser", 90 | "browserify", 91 | "buffer", 92 | "compatible", 93 | "dataview", 94 | "uint8array" 95 | ], 96 | "license": "MIT", 97 | "main": "index.js", 98 | "name": "buffer", 99 | "repository": { 100 | "type": "git", 101 | "url": "git://github.com/feross/buffer.git" 102 | }, 103 | "scripts": { 104 | "perf": "browserify --debug perf/bracket-notation.js > perf/bundle.js && open perf/index.html", 105 | "perf-node": "node perf/bracket-notation.js && node perf/concat.js && node perf/copy-big.js && node perf/copy.js && node perf/new-big.js && node perf/new.js && node perf/readDoubleBE.js && node perf/readFloatBE.js && node perf/readUInt32LE.js && node perf/slice.js && node perf/writeFloatBE.js", 106 | "size": "browserify -r ./ | uglifyjs -c -m | gzip | wc -c", 107 | "test": "standard && node ./bin/test.js", 108 | "test-browser-new": "airtap -- test/*.js test/node/*.js", 109 | "test-browser-new-local": "airtap --local -- test/*.js test/node/*.js", 110 | "test-browser-old": "airtap -- test/*.js", 111 | "test-browser-old-local": "airtap --local -- test/*.js", 112 | "test-node": "tape test/*.js test/node/*.js", 113 | "update-authors": "./bin/update-authors.sh" 114 | }, 115 | "standard": { 116 | "ignore": [ 117 | "test/node/**/*.js", 118 | "test/common.js", 119 | "test/_polyfill.js", 120 | "perf/**/*.js" 121 | ] 122 | }, 123 | "types": "index.d.ts", 124 | "version": "6.0.3" 125 | } 126 | -------------------------------------------------------------------------------- /node_modules/ieee754/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008 Fair Oaks Labs, Inc. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /node_modules/ieee754/README.md: -------------------------------------------------------------------------------- 1 | # ieee754 [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] 2 | 3 | [travis-image]: https://img.shields.io/travis/feross/ieee754/master.svg 4 | [travis-url]: https://travis-ci.org/feross/ieee754 5 | [npm-image]: https://img.shields.io/npm/v/ieee754.svg 6 | [npm-url]: https://npmjs.org/package/ieee754 7 | [downloads-image]: https://img.shields.io/npm/dm/ieee754.svg 8 | [downloads-url]: https://npmjs.org/package/ieee754 9 | [standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg 10 | [standard-url]: https://standardjs.com 11 | 12 | [![saucelabs][saucelabs-image]][saucelabs-url] 13 | 14 | [saucelabs-image]: https://saucelabs.com/browser-matrix/ieee754.svg 15 | [saucelabs-url]: https://saucelabs.com/u/ieee754 16 | 17 | ### Read/write IEEE754 floating point numbers from/to a Buffer or array-like object. 18 | 19 | ## install 20 | 21 | ``` 22 | npm install ieee754 23 | ``` 24 | 25 | ## methods 26 | 27 | `var ieee754 = require('ieee754')` 28 | 29 | The `ieee754` object has the following functions: 30 | 31 | ``` 32 | ieee754.read = function (buffer, offset, isLE, mLen, nBytes) 33 | ieee754.write = function (buffer, value, offset, isLE, mLen, nBytes) 34 | ``` 35 | 36 | The arguments mean the following: 37 | 38 | - buffer = the buffer 39 | - offset = offset into the buffer 40 | - value = value to set (only for `write`) 41 | - isLe = is little endian? 42 | - mLen = mantissa length 43 | - nBytes = number of bytes 44 | 45 | ## what is ieee754? 46 | 47 | The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point computation. [Read more](http://en.wikipedia.org/wiki/IEEE_floating_point). 48 | 49 | ## license 50 | 51 | BSD 3 Clause. Copyright (c) 2008, Fair Oaks Labs, Inc. 52 | -------------------------------------------------------------------------------- /node_modules/ieee754/index.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace ieee754 { 2 | export function read( 3 | buffer: Uint8Array, offset: number, isLE: boolean, mLen: number, 4 | nBytes: number): number; 5 | export function write( 6 | buffer: Uint8Array, value: number, offset: number, isLE: boolean, 7 | mLen: number, nBytes: number): void; 8 | } 9 | 10 | export = ieee754; -------------------------------------------------------------------------------- /node_modules/ieee754/index.js: -------------------------------------------------------------------------------- 1 | /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ 2 | exports.read = function (buffer, offset, isLE, mLen, nBytes) { 3 | var e, m 4 | var eLen = (nBytes * 8) - mLen - 1 5 | var eMax = (1 << eLen) - 1 6 | var eBias = eMax >> 1 7 | var nBits = -7 8 | var i = isLE ? (nBytes - 1) : 0 9 | var d = isLE ? -1 : 1 10 | var s = buffer[offset + i] 11 | 12 | i += d 13 | 14 | e = s & ((1 << (-nBits)) - 1) 15 | s >>= (-nBits) 16 | nBits += eLen 17 | for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} 18 | 19 | m = e & ((1 << (-nBits)) - 1) 20 | e >>= (-nBits) 21 | nBits += mLen 22 | for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} 23 | 24 | if (e === 0) { 25 | e = 1 - eBias 26 | } else if (e === eMax) { 27 | return m ? NaN : ((s ? -1 : 1) * Infinity) 28 | } else { 29 | m = m + Math.pow(2, mLen) 30 | e = e - eBias 31 | } 32 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen) 33 | } 34 | 35 | exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { 36 | var e, m, c 37 | var eLen = (nBytes * 8) - mLen - 1 38 | var eMax = (1 << eLen) - 1 39 | var eBias = eMax >> 1 40 | var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) 41 | var i = isLE ? 0 : (nBytes - 1) 42 | var d = isLE ? 1 : -1 43 | var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 44 | 45 | value = Math.abs(value) 46 | 47 | if (isNaN(value) || value === Infinity) { 48 | m = isNaN(value) ? 1 : 0 49 | e = eMax 50 | } else { 51 | e = Math.floor(Math.log(value) / Math.LN2) 52 | if (value * (c = Math.pow(2, -e)) < 1) { 53 | e-- 54 | c *= 2 55 | } 56 | if (e + eBias >= 1) { 57 | value += rt / c 58 | } else { 59 | value += rt * Math.pow(2, 1 - eBias) 60 | } 61 | if (value * c >= 2) { 62 | e++ 63 | c /= 2 64 | } 65 | 66 | if (e + eBias >= eMax) { 67 | m = 0 68 | e = eMax 69 | } else if (e + eBias >= 1) { 70 | m = ((value * c) - 1) * Math.pow(2, mLen) 71 | e = e + eBias 72 | } else { 73 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) 74 | e = 0 75 | } 76 | } 77 | 78 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} 79 | 80 | e = (e << mLen) | m 81 | eLen += mLen 82 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} 83 | 84 | buffer[offset + i - d] |= s * 128 85 | } 86 | -------------------------------------------------------------------------------- /node_modules/ieee754/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "ieee754@^1.2.1", 3 | "_id": "ieee754@1.2.1", 4 | "_inBundle": false, 5 | "_integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 6 | "_location": "/ieee754", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "ieee754@^1.2.1", 12 | "name": "ieee754", 13 | "escapedName": "ieee754", 14 | "rawSpec": "^1.2.1", 15 | "saveSpec": null, 16 | "fetchSpec": "^1.2.1" 17 | }, 18 | "_requiredBy": [ 19 | "/buffer" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 22 | "_shasum": "8eb7a10a63fff25d15a57b001586d177d1b0d352", 23 | "_spec": "ieee754@^1.2.1", 24 | "_where": "C:\\full_stack_oauth2\\node_modules\\buffer", 25 | "author": { 26 | "name": "Feross Aboukhadijeh", 27 | "email": "feross@feross.org", 28 | "url": "https://feross.org" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/feross/ieee754/issues" 32 | }, 33 | "bundleDependencies": false, 34 | "contributors": [ 35 | { 36 | "name": "Romain Beauxis", 37 | "email": "toots@rastageeks.org" 38 | } 39 | ], 40 | "deprecated": false, 41 | "description": "Read/write IEEE754 floating point numbers from/to a Buffer or array-like object", 42 | "devDependencies": { 43 | "airtap": "^3.0.0", 44 | "standard": "*", 45 | "tape": "^5.0.1" 46 | }, 47 | "funding": [ 48 | { 49 | "type": "github", 50 | "url": "https://github.com/sponsors/feross" 51 | }, 52 | { 53 | "type": "patreon", 54 | "url": "https://www.patreon.com/feross" 55 | }, 56 | { 57 | "type": "consulting", 58 | "url": "https://feross.org/support" 59 | } 60 | ], 61 | "homepage": "https://github.com/feross/ieee754#readme", 62 | "keywords": [ 63 | "IEEE 754", 64 | "buffer", 65 | "convert", 66 | "floating point", 67 | "ieee754" 68 | ], 69 | "license": "BSD-3-Clause", 70 | "main": "index.js", 71 | "name": "ieee754", 72 | "repository": { 73 | "type": "git", 74 | "url": "git://github.com/feross/ieee754.git" 75 | }, 76 | "scripts": { 77 | "test": "standard && npm run test-node && npm run test-browser", 78 | "test-browser": "airtap -- test/*.js", 79 | "test-browser-local": "airtap --local -- test/*.js", 80 | "test-node": "tape test/*.js" 81 | }, 82 | "types": "index.d.ts", 83 | "version": "1.2.1" 84 | } 85 | -------------------------------------------------------------------------------- /oauth2_angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /oauth2_angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /oauth2_angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /oauth2_angular/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 3 | "recommendations": ["angular.ng-template"] 4 | } 5 | -------------------------------------------------------------------------------- /oauth2_angular/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "ng serve", 7 | "type": "pwa-chrome", 8 | "request": "launch", 9 | "preLaunchTask": "npm: start", 10 | "url": "http://localhost:4200/" 11 | }, 12 | { 13 | "name": "ng test", 14 | "type": "chrome", 15 | "request": "launch", 16 | "preLaunchTask": "npm: test", 17 | "url": "http://localhost:9876/debug.html" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /oauth2_angular/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 3 | "version": "2.0.0", 4 | "tasks": [ 5 | { 6 | "type": "npm", 7 | "script": "start", 8 | "isBackground": true, 9 | "problemMatcher": { 10 | "owner": "typescript", 11 | "pattern": "$tsc", 12 | "background": { 13 | "activeOnStart": true, 14 | "beginsPattern": { 15 | "regexp": "(.*?)" 16 | }, 17 | "endsPattern": { 18 | "regexp": "bundle generation complete" 19 | } 20 | } 21 | } 22 | }, 23 | { 24 | "type": "npm", 25 | "script": "test", 26 | "isBackground": true, 27 | "problemMatcher": { 28 | "owner": "typescript", 29 | "pattern": "$tsc", 30 | "background": { 31 | "activeOnStart": true, 32 | "beginsPattern": { 33 | "regexp": "(.*?)" 34 | }, 35 | "endsPattern": { 36 | "regexp": "bundle generation complete" 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /oauth2_angular/README.md: -------------------------------------------------------------------------------- 1 | # Install Angular CLI 2 | 3 | `npm i -g @angular/cli` 4 | `sudo npm i -g @angular/cli` 5 | 6 | # Start the project 7 | 8 | `npm install` to install packages 9 | `npm start` starting the application 10 | 11 | # Stop previous application 12 | 13 | `netstat -aon | grep 3000` command will give us the port 14 | `tskill ` for windows 15 | `npx kill-port 3000` for MAC 16 | 17 | # Create app-routing module and tie it to app module 18 | 19 | `ng generate module app-routing --module app --flat` same command as 20 | `ng g m app-routing --module app --flat` 21 | 22 | # Create AuthComponent 23 | 24 | `ng g c auth --module app` 25 | 26 | # Create HomeComponent 27 | 28 | `ng g c home --module app` 29 | 30 | # Install buffer package for base64 encoding 31 | 32 | `npm i buffer` 33 | -------------------------------------------------------------------------------- /oauth2_angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "oauth2_angular": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:application": { 10 | "strict": true 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:browser", 19 | "options": { 20 | "outputPath": "dist/oauth2_angular", 21 | "index": "src/index.html", 22 | "main": "src/main.ts", 23 | "polyfills": "src/polyfills.ts", 24 | "tsConfig": "tsconfig.app.json", 25 | "assets": [ 26 | "src/favicon.ico", 27 | "src/assets" 28 | ], 29 | "styles": [ 30 | "src/styles.css" 31 | ], 32 | "scripts": [] 33 | }, 34 | "configurations": { 35 | "production": { 36 | "budgets": [ 37 | { 38 | "type": "initial", 39 | "maximumWarning": "500kb", 40 | "maximumError": "1mb" 41 | }, 42 | { 43 | "type": "anyComponentStyle", 44 | "maximumWarning": "2kb", 45 | "maximumError": "4kb" 46 | } 47 | ], 48 | "fileReplacements": [ 49 | { 50 | "replace": "src/environments/environment.ts", 51 | "with": "src/environments/environment.prod.ts" 52 | } 53 | ], 54 | "outputHashing": "all" 55 | }, 56 | "development": { 57 | "buildOptimizer": false, 58 | "optimization": false, 59 | "vendorChunk": true, 60 | "extractLicenses": false, 61 | "sourceMap": true, 62 | "namedChunks": true 63 | } 64 | }, 65 | "defaultConfiguration": "production" 66 | }, 67 | "serve": { 68 | "builder": "@angular-devkit/build-angular:dev-server", 69 | "configurations": { 70 | "production": { 71 | "browserTarget": "oauth2_angular:build:production" 72 | }, 73 | "development": { 74 | "browserTarget": "oauth2_angular:build:development" 75 | } 76 | }, 77 | "defaultConfiguration": "development" 78 | }, 79 | "extract-i18n": { 80 | "builder": "@angular-devkit/build-angular:extract-i18n", 81 | "options": { 82 | "browserTarget": "oauth2_angular:build" 83 | } 84 | }, 85 | "test": { 86 | "builder": "@angular-devkit/build-angular:karma", 87 | "options": { 88 | "main": "src/test.ts", 89 | "polyfills": "src/polyfills.ts", 90 | "tsConfig": "tsconfig.spec.json", 91 | "karmaConfig": "karma.conf.js", 92 | "assets": [ 93 | "src/favicon.ico", 94 | "src/assets" 95 | ], 96 | "styles": [ 97 | "src/styles.css" 98 | ], 99 | "scripts": [] 100 | } 101 | } 102 | } 103 | } 104 | }, 105 | "defaultProject": "oauth2_angular" 106 | } 107 | -------------------------------------------------------------------------------- /oauth2_angular/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | jasmine: { 17 | // you can add configuration options for Jasmine here 18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 19 | // for example, you can disable the random execution with `random: false` 20 | // or set a specific seed with `seed: 4321` 21 | }, 22 | clearContext: false // leave Jasmine Spec Runner output visible in browser 23 | }, 24 | jasmineHtmlReporter: { 25 | suppressAll: true // removes the duplicated traces 26 | }, 27 | coverageReporter: { 28 | dir: require('path').join(__dirname, './coverage/oauth2_angular'), 29 | subdir: '.', 30 | reporters: [ 31 | { type: 'html' }, 32 | { type: 'text-summary' } 33 | ] 34 | }, 35 | reporters: ['progress', 'kjhtml'], 36 | port: 9876, 37 | colors: true, 38 | logLevel: config.LOG_INFO, 39 | autoWatch: true, 40 | browsers: ['Chrome'], 41 | singleRun: false, 42 | restartOnFileChange: true 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /oauth2_angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oauth2-angular", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve --port 3000", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "~13.2.0", 14 | "@angular/common": "~13.2.0", 15 | "@angular/compiler": "~13.2.0", 16 | "@angular/core": "~13.2.0", 17 | "@angular/forms": "~13.2.0", 18 | "@angular/platform-browser": "~13.2.0", 19 | "@angular/platform-browser-dynamic": "~13.2.0", 20 | "@angular/router": "~13.2.0", 21 | "rxjs": "~7.5.0", 22 | "tslib": "^2.3.0", 23 | "zone.js": "~0.11.4" 24 | }, 25 | "devDependencies": { 26 | "@angular-devkit/build-angular": "~13.2.5", 27 | "@angular/cli": "~13.2.5", 28 | "@angular/compiler-cli": "~13.2.0", 29 | "@types/jasmine": "~3.10.0", 30 | "@types/node": "^12.11.1", 31 | "jasmine-core": "~4.0.0", 32 | "karma": "~6.3.0", 33 | "karma-chrome-launcher": "~3.1.0", 34 | "karma-coverage": "~2.1.0", 35 | "karma-jasmine": "~4.0.0", 36 | "karma-jasmine-html-reporter": "~1.7.0", 37 | "typescript": "~4.5.2" 38 | } 39 | } -------------------------------------------------------------------------------- /oauth2_angular/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { RouterModule } from '@angular/router'; 4 | import routes from './app.routes'; 5 | 6 | @NgModule({ 7 | declarations: [], 8 | imports: [ 9 | CommonModule, 10 | RouterModule.forRoot(routes) 11 | ], 12 | exports: [RouterModule] 13 | }) 14 | export class AppRoutingModule { } 15 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/app/app.component.css -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | }); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'oauth2_angular'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.componentInstance; 22 | expect(app.title).toEqual('oauth2_angular'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.nativeElement as HTMLElement; 29 | expect(compiled.querySelector('.content span')?.textContent).toContain('oauth2_angular app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'oauth2_angular'; 10 | } 11 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { AppRoutingModule } from './app-routing.module'; 6 | import { AuthComponent } from './auth/auth.component'; 7 | import { HomeComponent } from './home/home.component'; 8 | import { HttpClientModule } from '@angular/common/http'; 9 | import { LoginComponent } from './login/login.component'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | AppComponent, 14 | AuthComponent, 15 | HomeComponent, 16 | LoginComponent 17 | ], 18 | imports: [ 19 | BrowserModule, 20 | AppRoutingModule, 21 | HttpClientModule 22 | ], 23 | providers: [], 24 | bootstrap: [AppComponent] 25 | }) 26 | export class AppModule { } 27 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { HomeComponent } from "./home/home.component"; 2 | import { AuthComponent } from "./auth/auth.component"; 3 | import { LoginComponent } from "./login/login.component"; 4 | 5 | const routes = [ 6 | { path: 'home', component: HomeComponent, pathMatch: 'full'}, 7 | { path: 'auth', component: AuthComponent, pathMatch: 'full'}, 8 | { path: '', redirectTo: "auth", pathMatch: 'full'}, 9 | { path: 'authorized', redirectTo: "auth", pathMatch: 'full'}, 10 | { path: 'login', component: LoginComponent, pathMatch: 'full'} 11 | ]; 12 | 13 | export default routes; 14 | 15 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/auth/auth.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/app/auth/auth.component.css -------------------------------------------------------------------------------- /oauth2_angular/src/app/auth/auth.component.html: -------------------------------------------------------------------------------- 1 |

auth works!

2 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/auth/auth.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthComponent } from './auth.component'; 4 | 5 | describe('AuthComponent', () => { 6 | let component: AuthComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ AuthComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AuthComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/auth/auth.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from '../services/auth.service'; 3 | import { take } from 'rxjs/operators'; 4 | import { ActivatedRoute } from '@angular/router'; 5 | import { Router } from '@angular/router'; 6 | 7 | @Component({ 8 | selector: 'app-auth', 9 | templateUrl: './auth.component.html', 10 | styleUrls: ['./auth.component.css'] 11 | }) 12 | export class AuthComponent implements OnInit { 13 | 14 | constructor(private authService: AuthService, private activateRoute: ActivatedRoute, private router: Router) { 15 | this.getAuthorizationCode(); 16 | } 17 | 18 | ngOnInit(): void { 19 | this.authService.getToken().pipe(take(1)).subscribe((tokens) => { 20 | if((tokens as any)?.id_token){ 21 | sessionStorage.setItem('id_token', (tokens as any).id_token); 22 | sessionStorage.setItem('refresh_token', (tokens as any).refresh_token); 23 | this.router.navigate(['/home']); 24 | } 25 | }); 26 | } 27 | 28 | getAuthorizationCode() { 29 | this.activateRoute.queryParams.subscribe((params) => { 30 | if(params?.['code']){ 31 | this.authService.code = params['code']; 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/constants/demo.ts: -------------------------------------------------------------------------------- 1 | const demoUrl = () => { 2 | return 'http://127.0.0.1:9000/demo'; 3 | } 4 | 5 | export default demoUrl; -------------------------------------------------------------------------------- /oauth2_angular/src/app/constants/redirect.ts: -------------------------------------------------------------------------------- 1 | const redirectUrl = () => { 2 | const redirectUri = 'http://127.0.0.1:3000/authorized&code_challenge=QYPAZ5NU8yvtlQ9erXrUYR-T5AGCjCF47vN-KsaI2A8&code_challenge_method=S256'; 3 | return `http://localhost:8080/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=${redirectUri}`; 4 | } 5 | 6 | export default redirectUrl; -------------------------------------------------------------------------------- /oauth2_angular/src/app/constants/token.ts: -------------------------------------------------------------------------------- 1 | const tokenUrl = (code: string) => { 2 | const redirectUrl = `http://127.0.0.1:3000/authorized&grant_type=authorization_code&code=${code}&code_verifier=qPsH306-ZDDaOE8DFzVn05TkN3ZZoVmI_6x4LsVglQI`; 3 | return `http://localhost:8080/oauth2/token?client_id=client&redirect_uri=${redirectUrl}`; 4 | }; 5 | 6 | export default tokenUrl; -------------------------------------------------------------------------------- /oauth2_angular/src/app/home/home.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/app/home/home.component.css -------------------------------------------------------------------------------- /oauth2_angular/src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |

Welcome home

2 |

{{ demoContent }}

-------------------------------------------------------------------------------- /oauth2_angular/src/app/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HomeComponent } from './home.component'; 4 | 5 | describe('HomeComponent', () => { 6 | let component: HomeComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ HomeComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HomeComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { HttpHeaders } from '@angular/common/http'; 2 | import { Component, OnInit } from '@angular/core'; 3 | import demoUrl from '../constants/demo'; 4 | import { HttpService } from '../services/http.service'; 5 | import { take } from 'rxjs/operators'; 6 | 7 | @Component({ 8 | selector: 'app-home', 9 | templateUrl: './home.component.html', 10 | styleUrls: ['./home.component.css'] 11 | }) 12 | export class HomeComponent implements OnInit { 13 | 14 | constructor(private httpService: HttpService) { } 15 | 16 | public demoContent: string = ''; 17 | 18 | ngOnInit(): void { 19 | this.getDemoInformation(); 20 | } 21 | 22 | private getDemoInformation(){ 23 | const token = sessionStorage.getItem('id_token'); 24 | const bearerToken = `Bearer ${token}`; 25 | const options = { 26 | headers: new HttpHeaders({ 'Authorization': bearerToken }), 27 | responseType: 'text/plain' 28 | }; 29 | 30 | this.httpService.doGet(demoUrl(), options).pipe(take(1)).subscribe((content) => { 31 | console.log(content); 32 | //this.demoContent = content; 33 | (this.demoContent as any) = content; 34 | }) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/login/login.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/app/login/login.component.css -------------------------------------------------------------------------------- /oauth2_angular/src/app/login/login.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/login/login.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LoginComponent } from './login.component'; 4 | 5 | describe('LoginComponent', () => { 6 | let component: LoginComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ LoginComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LoginComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import redirectUrl from '../constants/redirect'; 4 | 5 | @Component({ 6 | selector: 'app-login', 7 | templateUrl: './login.component.html', 8 | styleUrls: ['./login.component.css'] 9 | }) 10 | export class LoginComponent implements OnInit { 11 | 12 | constructor() { } 13 | 14 | ngOnInit(): void { 15 | } 16 | 17 | redirect(){ 18 | window.location.href = redirectUrl(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /oauth2_angular/src/app/services/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpHeaders } from "@angular/common/http"; 2 | import { Injectable } from "@angular/core"; 3 | import { HttpService } from "./http.service"; 4 | import tokenUrl from "../constants/token"; 5 | import { Buffer } from 'buffer'; 6 | 7 | @Injectable({ providedIn: 'root' }) 8 | export class AuthService { 9 | public code: string = ''; 10 | 11 | 12 | constructor(private httpService: HttpService){ 13 | } 14 | 15 | getToken(){ 16 | const mockUserClient = 'client'; 17 | const mockUserSecret = 'secret'; 18 | const basicAuth = `Basic ` + Buffer.from(`${mockUserClient}:${mockUserSecret}`).toString('base64'); 19 | const headers = new HttpHeaders({ 20 | 'content-type': 'application/json', 21 | 'Authorization': basicAuth 22 | }); 23 | const options = { 24 | headers: headers 25 | } 26 | 27 | return this.httpService.doPost(tokenUrl(this.code), null, options); 28 | } 29 | } -------------------------------------------------------------------------------- /oauth2_angular/src/app/services/http.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 3 | 4 | @Injectable({ providedIn: 'root' }) 5 | export class HttpService { 6 | constructor(private httpClient: HttpClient) { 7 | } 8 | 9 | doPost(url: string, body: any, options: { headers: HttpHeaders } ) { 10 | return this.httpClient.post(url, body, options); 11 | } 12 | 13 | doGet(url: string, options: { headers: HttpHeaders }) { 14 | return this.httpClient.get(url, options); 15 | } 16 | 17 | doPut() { 18 | //etc 19 | } 20 | } -------------------------------------------------------------------------------- /oauth2_angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/assets/.gitkeep -------------------------------------------------------------------------------- /oauth2_angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth2_angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /oauth2_angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_angular/src/favicon.ico -------------------------------------------------------------------------------- /oauth2_angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Oauth2Angular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /oauth2_angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /oauth2_angular/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including 12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | * because those flags need to be set before `zone.js` being loaded, and webpack 25 | * will put import in the top of bundle, so user need to create a separate file 26 | * in this directory (for example: zone-flags.ts), and put the following flags 27 | * into that file, and then add the following code before importing zone.js. 28 | * import './zone-flags'; 29 | * 30 | * The flags allowed in zone-flags.ts are listed here. 31 | * 32 | * The following flags will work for all browsers. 33 | * 34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 37 | * 38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 40 | * 41 | * (window as any).__Zone_enable_cross_context_check = true; 42 | * 43 | */ 44 | 45 | /*************************************************************************************************** 46 | * Zone JS is required by default for Angular itself. 47 | */ 48 | import 'zone.js'; // Included with Angular CLI. 49 | 50 | 51 | /*************************************************************************************************** 52 | * APPLICATION IMPORTS 53 | */ 54 | -------------------------------------------------------------------------------- /oauth2_angular/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /oauth2_angular/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | (id: string): T; 13 | keys(): string[]; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting(), 21 | ); 22 | 23 | // Then we find all the tests. 24 | const context = require.context('./', true, /\.spec\.ts$/); 25 | // And load the modules. 26 | context.keys().map(context); 27 | -------------------------------------------------------------------------------- /oauth2_angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /oauth2_angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "es2017", 20 | "module": "es2020", 21 | "lib": [ 22 | "es2020", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /oauth2_angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /oauth2_react/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /oauth2_react/README.md: -------------------------------------------------------------------------------- 1 | # Creating react application 2 | 3 | - `npx create-react-app appName` 4 | 5 | # Installing react-router and react-router-dom 6 | 7 | - `npm i --save-dev react-router react-router-dom` 8 | 9 | # Installing buffer 10 | 11 | - `npm i buffer` 12 | 13 | # Installing crypto-js 14 | 15 | - `npm i --save-dev crypto-js` -------------------------------------------------------------------------------- /oauth2_react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oauth2_react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "buffer": "^6.0.3", 10 | "react": "^18.1.0", 11 | "react-dom": "^18.1.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | }, 39 | "devDependencies": { 40 | "crypto-js": "^4.1.1", 41 | "react-router": "^6.3.0", 42 | "react-router-dom": "^6.3.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /oauth2_react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_react/public/favicon.ico -------------------------------------------------------------------------------- /oauth2_react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /oauth2_react/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_react/public/logo192.png -------------------------------------------------------------------------------- /oauth2_react/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/oauth2_react/public/logo512.png -------------------------------------------------------------------------------- /oauth2_react/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /oauth2_react/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /oauth2_react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /oauth2_react/src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Routes, Route } from 'react-router-dom'; 2 | import Login from './components/Login'; 3 | import Redirect from './components/Redirect'; 4 | import Home from './components/Home'; 5 | 6 | function App() { 7 | const home = '/home'; 8 | return ( 9 |
10 | 11 | 12 | } /> 13 | } /> 14 | } /> 15 | } /> 16 | 17 | 18 |
19 | ); 20 | } 21 | 22 | export default App; 23 | -------------------------------------------------------------------------------- /oauth2_react/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /oauth2_react/src/components/Home.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import { demo } from '../links/demo'; 3 | const Home = () => { 4 | const [demoStr, setDemoStr] = useState('default'); 5 | useEffect(() => { 6 | const token = sessionStorage.getItem('id_token'); 7 | const headers = new Headers(); 8 | headers.set('Content-type', 'plain/text'); 9 | headers.set('Authorization', `Bearer ${token}`); 10 | const url = demo(); 11 | fetch(url, { 12 | method: 'GET', 13 | mode: 'cors', 14 | headers 15 | }).then(async (demoData) => { 16 | const demo = await demoData.text(); 17 | setDemoStr(demo); 18 | }) 19 | 20 | }, []); 21 | return <> 22 |
23 |

Home

24 |
25 |
26 |

{demoStr}

27 |
28 | ; 29 | } 30 | 31 | export default Home; -------------------------------------------------------------------------------- /oauth2_react/src/components/Login.js: -------------------------------------------------------------------------------- 1 | import { React } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { generateCodeChallenge, generateCodeVerifier } from '../pkce/pkce'; 4 | const Login = () => { 5 | const verifier = generateCodeVerifier(); 6 | sessionStorage.setItem('codeVerifier', verifier); 7 | const codeChallenge = generateCodeChallenge(); 8 | sessionStorage.setItem('codeChallenge', codeChallenge); 9 | return ( 10 | <> 11 | Login 12 | 13 | ); 14 | } 15 | 16 | export default Login; -------------------------------------------------------------------------------- /oauth2_react/src/components/Redirect.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useSearchParams, useNavigate } from "react-router-dom"; 3 | import { Buffer } from "buffer"; 4 | 5 | const Redirect = () => { 6 | const [searchParams] = useSearchParams(); 7 | const navigate = useNavigate(); 8 | 9 | useEffect(() => { 10 | if(searchParams?.get('code')){ 11 | const code = searchParams?.get('code'); 12 | const client = 'client'; 13 | const secret = 'secret'; 14 | const headers = new Headers(); 15 | headers.append('Content-type', 'application/json'); 16 | headers.append('Authorization', `Basic ${Buffer.from(`${client}:${secret}`).toString('base64')}`); 17 | 18 | const verifier = sessionStorage.getItem('codeVerifier'); 19 | 20 | const initialUrl = 'http://localhost:8080/oauth2/token?client_id=client&redirect_uri=http://127.0.0.1:3000/authorized&grant_type=authorization_code'; 21 | const url = `${initialUrl}&code=${code}&code_verifier=${verifier}`; 22 | 23 | fetch(url, { 24 | method: 'POST', 25 | mode: 'cors', 26 | headers 27 | }).then(async (response) => { 28 | const token = await response.json(); 29 | if(token?.id_token) { 30 | sessionStorage.setItem('id_token', token.id_token); 31 | navigate('/home'); 32 | } 33 | }).catch((err) => { 34 | console.log(err); 35 | }) 36 | } 37 | }, []); 38 | useEffect(() => { 39 | if(!searchParams?.get('code')){ 40 | const codeChallenge = sessionStorage.getItem('codeChallenge'); 41 | const link = `http://localhost:8080/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=http://127.0.0.1:3000/authorized&code_challenge=${codeChallenge}&code_challenge_method=S256`; 42 | 43 | window.location.href = link; 44 | } 45 | }, []); 46 | return

Redirecting ...

47 | } 48 | 49 | export default Redirect; -------------------------------------------------------------------------------- /oauth2_react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /oauth2_react/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /oauth2_react/src/links/demo.js: -------------------------------------------------------------------------------- 1 | const demo = () => { 2 | return 'http://127.0.0.1:9000/demo'; 3 | } 4 | 5 | export {demo}; -------------------------------------------------------------------------------- /oauth2_react/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /oauth2_react/src/pkce/pkce.js: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto-js'; 2 | import sha256 from 'crypto-js/sha256'; 3 | import Base64 from 'crypto-js/enc-base64'; 4 | 5 | const base64Url = (str) => { 6 | return str.toString(Base64).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); 7 | } 8 | 9 | const generateCodeVerifier = () => { 10 | return base64Url(crypto.enc.Base64.stringify(crypto.lib.WordArray.random(32))); 11 | } 12 | 13 | const generateCodeChallenge = () => { 14 | const codeVerifier = sessionStorage.getItem('codeVerifier'); 15 | return base64Url(sha256(codeVerifier)); 16 | } 17 | 18 | export { 19 | base64Url, 20 | generateCodeVerifier, 21 | generateCodeChallenge 22 | } -------------------------------------------------------------------------------- /oauth2_react/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /oauth2_react/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "base64-js": { 6 | "version": "1.5.1", 7 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 8 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 9 | }, 10 | "buffer": { 11 | "version": "6.0.3", 12 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 13 | "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 14 | "requires": { 15 | "base64-js": "^1.3.1", 16 | "ieee754": "^1.2.1" 17 | } 18 | }, 19 | "ieee754": { 20 | "version": "1.2.1", 21 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 22 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resource-server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /resource-server/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lspil/full_stack_oauth2/d6b1ec0800ba718a65dd48b8014dfeb7d4c5861a/resource-server/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /resource-server/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /resource-server/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /resource-server/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /resource-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.0.1 9 | 10 | 11 | com.example 12 | resource-server 13 | 0.0.1-SNAPSHOT 14 | resource-server 15 | resource-server 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-oauth2-resource-server 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-security 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.projectlombok 35 | lombok 36 | true 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.springframework.security 45 | spring-security-test 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | org.projectlombok 59 | lombok 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /resource-server/src/main/java/com/example/resourceserver/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.resourceserver; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ResourceServerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /resource-server/src/main/java/com/example/resourceserver/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.resourceserver.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.web.SecurityFilterChain; 7 | import org.springframework.web.cors.CorsConfiguration; 8 | import org.springframework.web.cors.CorsConfigurationSource; 9 | 10 | import java.util.List; 11 | 12 | @Configuration 13 | public class SecurityConfig { 14 | 15 | @Bean 16 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 17 | http.cors(c -> { 18 | CorsConfigurationSource source = s -> { 19 | CorsConfiguration cc = new CorsConfiguration(); 20 | cc.setAllowCredentials(true); 21 | cc.setAllowedOrigins(List.of("http://127.0.0.1:3000")); 22 | cc.setAllowedHeaders(List.of("*")); 23 | cc.setAllowedMethods(List.of("*")); 24 | return cc; 25 | }; 26 | 27 | c.configurationSource(source); 28 | }); 29 | 30 | http.authorizeHttpRequests().anyRequest() 31 | .authenticated().and() 32 | .oauth2ResourceServer() 33 | .jwt(); 34 | return http.build(); 35 | } 36 | 37 | } 38 | 39 | // http://localhost:8080/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=http://localhost:3000/authorized&code_challenge=QYPAZ5NU8yvtlQ9erXrUYR-T5AGCjCF47vN-KsaI2A8&code_challenge_method=S256 40 | -------------------------------------------------------------------------------- /resource-server/src/main/java/com/example/resourceserver/controllers/DemoController.java: -------------------------------------------------------------------------------- 1 | package com.example.resourceserver.controllers; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class DemoController { 8 | 9 | @GetMapping("/demo") 10 | public String demo() { 11 | return "Demo"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resource-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9000 2 | spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080 -------------------------------------------------------------------------------- /resource-server/src/test/java/com/example/resourceserver/ResourceServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.resourceserver; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ResourceServerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------