Skip to content

Commit 54bdd96

Browse files
author
sampadawagde
committed
JAVA-1132: Added clients-SPA-legacy, also renamed underlying modules to
suffix -legacy
1 parent 7a209a2 commit 54bdd96

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2394
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
4+
### STS ###
5+
.apt_generated
6+
.classpath
7+
.factorypath
8+
.project
9+
.settings
10+
.springBeans
11+
.sts4-cache
12+
13+
### IntelliJ IDEA ###
14+
.idea
15+
*.iws
16+
*.iml
17+
*.ipr
18+
19+
### NetBeans ###
20+
/nbproject/private/
21+
/nbbuild/
22+
/dist/
23+
/nbdist/
24+
/.nb-gradle/
25+
/build/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<artifactId>clients-js-only-react-legacy</artifactId>
7+
<version>0.0.1-SNAPSHOT</version>
8+
<name>clients-js-only-react-legacy</name>
9+
<description>Demo project for Spring Boot</description>
10+
11+
<parent>
12+
<groupId>com.baeldung</groupId>
13+
<artifactId>spring-security-oauth</artifactId>
14+
<version>1.0.0-SNAPSHOT</version>
15+
<relativePath>../../</relativePath>
16+
</parent>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-web</artifactId>
22+
</dependency>
23+
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-test</artifactId>
27+
<scope>test</scope>
28+
</dependency>
29+
</dependencies>
30+
31+
<build>
32+
<plugins>
33+
<plugin>
34+
<groupId>org.springframework.boot</groupId>
35+
<artifactId>spring-boot-maven-plugin</artifactId>
36+
</plugin>
37+
</plugins>
38+
</build>
39+
40+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.baeldung.clientjsonlyreact;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class ClientJsOnlyReactApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(ClientJsOnlyReactApplication.class, args);
11+
}
12+
13+
}

clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/application.properties

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
function generate_code_challenge(verifier) {
2+
return base64_urlencode(sha256bin(verifier));
3+
}
4+
5+
generateCodeChallenge = async (codeVerifier) => {
6+
const strBuffer = new TextEncoder('utf-8').encode(codeVerifier);
7+
const hashBuffer = await window.crypto.subtle.digest('SHA-256', strBuffer);
8+
return Array.from(new Uint8Array(hashBuffer));
9+
}
10+
11+
function sha256bin(ascii) {
12+
return hex2bin(sha256(ascii));
13+
}
14+
15+
function hex2bin(s) {
16+
17+
var ret = []
18+
var i = 0
19+
var l
20+
21+
s += ''
22+
23+
for (l = s.length; i < l; i += 2) {
24+
var c = parseInt(s.substr(i, 1), 16)
25+
var k = parseInt(s.substr(i + 1, 1), 16)
26+
if (isNaN(c) || isNaN(k)) return false
27+
ret.push((c << 4) | k)
28+
}
29+
30+
return String.fromCharCode.apply(String, ret)
31+
}
32+
33+
var sha256 = function sha256(ascii) {
34+
function rightRotate(value, amount) {
35+
return (value>>>amount) | (value<<(32 - amount));
36+
};
37+
38+
var mathPow = Math.pow;
39+
var maxWord = mathPow(2, 32);
40+
var lengthProperty = 'length';
41+
var i, j; // Used as a counter across the whole file
42+
var result = '';
43+
44+
var words = [];
45+
var asciiBitLength = ascii[lengthProperty]*8;
46+
47+
//* caching results is optional - remove/add slash from front of this line to toggle
48+
// Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes
49+
// (we actually calculate the first 64, but extra values are just ignored)
50+
var hash = sha256.h = sha256.h || [];
51+
// Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes
52+
var k = sha256.k = sha256.k || [];
53+
var primeCounter = k[lengthProperty];
54+
/*/
55+
var hash = [], k = [];
56+
var primeCounter = 0;
57+
//*/
58+
59+
var isComposite = {};
60+
for (var candidate = 2; primeCounter < 64; candidate++) {
61+
if (!isComposite[candidate]) {
62+
for (i = 0; i < 313; i += candidate) {
63+
isComposite[i] = candidate;
64+
}
65+
hash[primeCounter] = (mathPow(candidate, .5)*maxWord)|0;
66+
k[primeCounter++] = (mathPow(candidate, 1/3)*maxWord)|0;
67+
}
68+
}
69+
70+
ascii += '\x80'; // Append '1' bit (plus zero padding)
71+
while (ascii[lengthProperty]%64 - 56) ascii += '\x00'; // More zero padding
72+
for (i = 0; i < ascii[lengthProperty]; i++) {
73+
j = ascii.charCodeAt(i);
74+
if (j>>8) return; // ASCII check: only accept characters in range 0-255
75+
words[i>>2] |= j << ((3 - i)%4)*8;
76+
}
77+
words[words[lengthProperty]] = ((asciiBitLength/maxWord)|0);
78+
words[words[lengthProperty]] = (asciiBitLength)
79+
80+
// process each chunk
81+
for (j = 0; j < words[lengthProperty];) {
82+
var w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration
83+
var oldHash = hash;
84+
// This is now the "working hash", often labelled as variables a...g
85+
// (we have to truncate as well, otherwise extra entries at the end accumulate
86+
hash = hash.slice(0, 8);
87+
88+
for (i = 0; i < 64; i++) {
89+
var i2 = i + j;
90+
// Expand the message into 64 words
91+
// Used below if
92+
var w15 = w[i - 15], w2 = w[i - 2];
93+
94+
// Iterate
95+
var a = hash[0], e = hash[4];
96+
var temp1 = hash[7]
97+
+ (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
98+
+ ((e&hash[5])^((~e)&hash[6])) // ch
99+
+ k[i]
100+
// Expand the message schedule if needed
101+
+ (w[i] = (i < 16) ? w[i] : (
102+
w[i - 16]
103+
+ (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15>>>3)) // s0
104+
+ w[i - 7]
105+
+ (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2>>>10)) // s1
106+
)|0
107+
);
108+
// This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble
109+
var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
110+
+ ((a&hash[1])^(a&hash[2])^(hash[1]&hash[2])); // maj
111+
112+
hash = [(temp1 + temp2)|0].concat(hash); // We don't bother trimming off the extra ones, they're harmless as long as we're truncating when we do the slice()
113+
hash[4] = (hash[4] + temp1)|0;
114+
}
115+
116+
for (i = 0; i < 8; i++) {
117+
hash[i] = (hash[i] + oldHash[i])|0;
118+
}
119+
}
120+
121+
for (i = 0; i < 8; i++) {
122+
for (j = 3; j + 1; j--) {
123+
var b = (hash[i]>>(j*8))&255;
124+
result += ((b < 16) ? 0 : '') + b.toString(16);
125+
}
126+
}
127+
return result;
128+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function generate_code_verifier() {
2+
return random_string(48);
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function base64_urlencode(str) {
2+
return btoa(str)
3+
.replace(/\+/g, '-')
4+
.replace(/\//g, '_')
5+
.replace(/=/g, '');
6+
}
7+
8+
function generate_state() {
9+
return random_string(48);
10+
}
11+
12+
function random_string(len) {
13+
var arr = new Uint8Array(len);
14+
window.crypto.getRandomValues(arr);
15+
var str = base64_urlencode(dec2bin(arr));
16+
return str.substring(0, len);
17+
}
18+
19+
function dec2hex(dec) {
20+
return ('0' + dec.toString(16)).substr(-2)
21+
}
22+
23+
function dec2bin(arr) {
24+
return hex2bin(Array.from(arr, dec2hex).join(''));
25+
}
26+
27+
function getParameterByName(name, url) {
28+
if (!url) url = window.location.href;
29+
name = name.replace(/[\[\]]/g, '\\$&');
30+
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
31+
results = regex.exec(url);
32+
if (!results) return null;
33+
if (!results[2]) return '';
34+
return decodeURIComponent(results[2].replace(/\+/g, ' '));
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Spiner indicating something is being processed
2+
const Spinner = ({ spinnerText }) => (
3+
<div className="spinner-container">
4+
<p className="spinner-text">{spinnerText || 'Waiting...'}</p>
5+
<div className="spinner-icon"></div>
6+
</div>
7+
)
8+
9+
window.Spinner = Spinner;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const AUTH0_APP_DOMAIN = 'https://bael-jsonly-pkce.auth0.com';
2+
const PROVIDER_CONFIGS = {
3+
AUTH0: {
4+
AUTH_URL: AUTH0_APP_DOMAIN + "/authorize",
5+
CLIENT_ID: "R7L3XpkJrwcGEkuxrUdSpGAA9NgX9ouQ",
6+
CONFIGURED_REDIRECT_URIS:{
7+
STEP_BY_STEP: "http://localhost:8080/pkce-stepbystep/popup_code_handler.html",
8+
REAL_CASE: "http://localhost:8080/pkce-realcase/popup_code_handler.html",
9+
SIMPLE: "http://localhost:8080/pkce-simple/callback.html"
10+
},
11+
TOKEN_URI: AUTH0_APP_DOMAIN + "/oauth/token",
12+
SCOPES: 'openid profile email',
13+
AUDIENCE: "pkceclient.baeldung.com",
14+
PROFILE_URL: AUTH0_APP_DOMAIN + "/userinfo",
15+
PROFILE_FIELDS: {
16+
NAME: "nickname",
17+
EMAIL: "email",
18+
PICTURE: "picture"
19+
},
20+
// Renew Token Period for in seconds:
21+
RENEW_TOKEN_PERIOD: 60
22+
}
23+
}
24+
25+
window.PROVIDER_CONFIGS = PROVIDER_CONFIGS;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Landing Page - Baeldung's JS-only SPA Oauth Client</title>
6+
<meta charset="UTF-8">
7+
<meta name="viewport" content="width=device-width">
8+
9+
<!-- Styles -->
10+
<link rel="stylesheet" href="/landing-page.css">
11+
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
12+
</head>
13+
14+
<body>
15+
16+
<div id="landing-page-container">
17+
<div class="header-container">
18+
<div class="title">
19+
<h1>
20+
Welcome to the JS-only SPA OAuth Clients using Auth Code with PKCE!
21+
</h1>
22+
</div>
23+
<div class="description">
24+
We present here three examples of Single Page Applications:
25+
</div>
26+
</div>
27+
<div class="examples-container">
28+
<a id="simple" href="/pkce-simple/index.html">
29+
<div class="example">
30+
<div class="title">
31+
<h2>The Article's Example SPA</h2>
32+
</div>
33+
<div class="description">
34+
<p>If we're looking for the application that we built together following the article's steps,
35+
this is our option.</p>
36+
<p>It has nothing but the most fundamental elements to access secured resources using the
37+
OAuth2 Auth Code with PKCE Flow</p>
38+
</div>
39+
</div>
40+
</a>
41+
<a id="step-by-step" href="/pkce-stepbystep/index.html">
42+
<div class="example">
43+
<div class="title">
44+
<h2>The Step-By-Step SPA</h2>
45+
</div>
46+
<div class="description">
47+
<p>We should pick this App if we want to see how the Auth Code with PKCE Flow is carried out in an interactive way.</p>
48+
<p>
49+
We'll see in the UI and in the browser console what happens behind the scenes when we request an
50+
access token.
51+
</p>
52+
</div>
53+
</div>
54+
</a>
55+
<a id="real-case" href="/pkce-realcase/index.html">
56+
<div class="example">
57+
<div class="title">
58+
<h2>The Real-Case SPA</h2>
59+
</div>
60+
<div class="description">
61+
<p>
62+
In this Application we simulate how a real application would work, making use of our custom Resource Server
63+
with protected endpoints. </p>
64+
<p>
65+
Remember to read The
66+
Readme file for more details.</p>
67+
</div>
68+
</div>
69+
</a>
70+
</div>
71+
</div>
72+
</body>
73+
74+
</html>

0 commit comments

Comments
 (0)