oauth-v2-client
Version:
Oauth V2 client based on axios
457 lines (413 loc) • 12.3 kB
text/typescript
import Axios from "axios";
import { json } from "body-parser";
import express, { Request } from "express";
import http from "http";
import { serialize, parse } from "cookie";
import { TokenResponse } from "../interfaces";
import OauthClient from "../OauthClient";
const app = express();
const httpServer = http.createServer(app);
const noreaApi = new OauthClient({
oauthOptions: {
clientId: "2a540634-da3a-4bd7-9273-964b4b5130e7",
clientSecret:
"62a5c0e896280d98378f27eb73df3020d7de3f863888b9ae3c2da45a908d2a07b9b785a4dd898a5ab7eda3210b466d62c3a7d701723b921b59e736f131183d3a",
callbackUrl: "http://127.0.0.1:8080/auth-code/callback",
accessTokenUrl: "http://localhost:8080/oauth/v2/token",
authUrl: "http://localhost:8080/oauth/v2/authorize",
},
requestOptions: {
body: {
baby: "boom",
},
headers: {
Accept: "application/json",
},
},
});
const implicitNoreaApi = new OauthClient({
oauthOptions: {
clientId: "2a540634-da3a-4bd7-9273-964b4b5130e7",
clientSecret:
"62a5c0e896280d98378f27eb73df3020d7de3f863888b9ae3c2da45a908d2a07b9b785a4dd898a5ab7eda3210b466d62c3a7d701723b921b59e736f131183d3a",
callbackUrl: "http://127.0.0.1:8080/implicit/callback",
accessTokenUrl: "http://localhost:3000/oauth/v2/token",
authUrl: "http://localhost:3000/oauth/v2/authorize",
},
requestOptions: {
body: {
baby: "boom",
},
headers: {
Accept: "application/json",
},
},
});
const authCodeNoreaApi = new OauthClient({
oauthOptions: {
clientId: "2a540634-da3a-4bd7-9273-964b4b5130e7",
clientSecret:
"62a5c0e896280d98378f27eb73df3020d7de3f863888b9ae3c2da45a908d2a07b9b785a4dd898a5ab7eda3210b466d62c3a7d701723b921b59e736f131183d3a",
callbackUrl: "http://127.0.0.1:8080/auth-code/callback",
accessTokenUrl: "http://localhost:3000/oauth/v2/token",
authUrl: "http://localhost:3000/oauth/v2/authorize",
},
requestOptions: {
body: {
baby: "boom",
},
headers: {
Accept: "application/json",
},
},
});
const authCodePkceNoreaApi = new OauthClient({
oauthOptions: {
clientId: "2a540634-da3a-4bd7-9273-964b4b5130e7",
clientSecret:
"62a5c0e896280d98378f27eb73df3020d7de3f863888b9ae3c2da45a908d2a07b9b785a4dd898a5ab7eda3210b466d62c3a7d701723b921b59e736f131183d3a",
callbackUrl: "http://127.0.0.1:8080/auth-code-pkce/callback",
accessTokenUrl: "http://localhost:3000/oauth/v2/token",
authUrl: "http://localhost:3000/oauth/v2/authorize",
},
requestOptions: {
body: {
baby: "boom",
},
headers: {
Accept: "application/json",
},
},
});
const githubApi = new OauthClient({
oauthOptions: {
clientId: "2ece8a82eeabbe5cf1f7",
clientSecret: "de81d702031313341f672883869192c46646bee0",
callbackUrl: "http://localhost:8080/github/callback",
accessTokenUrl: "https://github.com/login/oauth/access_token",
authUrl: "https://github.com/login/oauth/authorize",
},
requestOptions: {
headers: {
Accept: "application/json",
},
},
log: true
});
const gitlab = new OauthClient({
oauthOptions: {
clientId:
"a8f5ea8cb6b3f925da22607ecadb6b9ff05fb70f437abaa15517d8b66f132782",
clientSecret:
"3f87352110d6847701cff896d9e1f908f287ac258405c83d306105301f0beccb",
callbackUrl: "http://localhost:8080/gitlab/callback",
accessTokenUrl: "https://gitlab.com/oauth/token",
authUrl: "https://gitlab.com/oauth/authorize",
scopes: ["read_user"],
},
requestOptions: {
headers: {
Accept: "application/json",
},
},
});
const bitbucket = new OauthClient({
oauthOptions: {
clientId: "BzNLNrjmYKyM6navGg",
clientSecret: "TDvbZ5zVrtyWZct9ctXHs7PwMnGcEqbq",
callbackUrl: "http://localhost:8080/bitbucket/callback",
accessTokenUrl: "https://bitbucket.org/site/oauth2/access_token",
authUrl: "https://bitbucket.org/site/oauth2/authorize",
apiBaseURL: "https://api.bitbucket.org",
},
requestOptions: {
bodyType: "x-www-form-urlencoded",
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
},
});
/**
* Implicit
* --------------
*/
app.get("/oauth/implicit", function (req, res) {
const state = Math.random().toString(36);
console.log('implicit initial state:', state)
const stateCookieStr = serialize("oauth-v2-client-state", state, {
path: '/',
sameSite: 'lax',
priority: 'high',
maxAge: 60
})
res.setHeader('Set-Cookie', stateCookieStr)
res.redirect(implicitNoreaApi.implicit.getAuthUri({
state
}));
});
app.get("/implicit/callback", function (req, res) {
const cookie = parse(req.headers['cookie'] ?? '')
console.log('implicit response state:', cookie["oauth-v2-client-state"])
res.json(implicitNoreaApi.implicit.getToken(req.originalUrl, cookie["oauth-v2-client-state"]));
});
/**
* Authorization code
* -----------------------
*/
app.get("/oauth/auth-code", function (req, res) {
const state = Math.random().toString(36);
console.log('auth code initial state:', state)
const stateCookieStr = serialize("oauth-v2-client-state", state, {
path: '/',
sameSite: 'lax',
priority: 'high',
maxAge: 60
})
res.setHeader('Set-Cookie', stateCookieStr)
res.redirect(
authCodeNoreaApi.authorizationCode.getAuthUri({ state })
);
});
app.get("/auth-code/callback", async function (req, res) {
const cookie = parse(req.headers['cookie'] ?? '')
console.log('auth code response state:', cookie["oauth-v2-client-state"])
await authCodeNoreaApi.authorizationCode.getToken({
callbackUrl: req.originalUrl,
state: cookie["oauth-v2-client-state"],
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
if (Axios.isAxiosError(error)) {
res.status(500).json(error.response?.data);
} else {
res.status(500).json(error);
}
},
});
});
/**
* Authorization code PKCE
* ----------------------------
*/
app.get("/oauth/auth-code-pkce", function (req, res) {
const state = Math.random().toString(36);
console.log('auth code pkce initial state:', state)
const stateCookieStr = serialize("oauth-v2-client-state", state, {
path: '/',
sameSite: 'lax',
priority: 'high',
maxAge: 60
})
res.setHeader('Set-Cookie', stateCookieStr)
res.redirect(
authCodePkceNoreaApi.authorizationCodePKCE.getAuthUri({ codeVerifier: state })
);
});
app.get("/auth-code-pkce/callback", async function (req, res) {
const cookie = parse(req.headers['cookie'] ?? '')
console.log('auth code pkce response state:', cookie["oauth-v2-client-state"])
await authCodePkceNoreaApi.authorizationCodePKCE.getToken({
callbackUrl: req.originalUrl,
codeVerifier: cookie["oauth-v2-client-state"],
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
if (Axios.isAxiosError(error)) {
res.status(500).json(error.response?.data);
} else {
res.status(500).json(error);
}
},
});
});
/**
* Password
* -----------------------------------
*/
app.post("/oauth/password", [
json(),
async function (req: any, res: any) {
try {
await noreaApi.password.getToken({
username: req.body.username,
password: req.body.password,
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
});
} catch (error) {
return res.status(500).json((error as any).message);
}
},
]);
app.post("/oauth/password/refresh", async function (req: any, res: any) {
await noreaApi.password.refresh({
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
token: req.body
});
});
/**
* Client credentials
* -----------------------------------
*/
app.post("/oauth/client", [
json(),
async function (req: any, res: any) {
await noreaApi.client.getToken({
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
});
},
]);
/**
* Github Authorization code
* -----------------------
*/
app.get("/oauth/github", function (req: Request, res) {
const state = Math.random().toString(36);
const stateCookieStr = serialize("oauth-v2-client-state", state, {
path: '/',
sameSite: 'lax',
priority: 'high',
maxAge: 60
})
res.setHeader('Set-Cookie', stateCookieStr)
res.redirect(githubApi.authorizationCode.getAuthUri({
state
}));
});
app.get("/github/callback", async function (req: Request, res) {
try {
const cookie = parse(req.headers['cookie'] ?? '')
console.log("cookie", req.url)
const response = await new Promise<TokenResponse>((resolve, reject) => {
githubApi.authorizationCode.getToken({
state: cookie["oauth-v2-client-state"],
callbackUrl: `${req.protocol}://${req.hostname}${req.originalUrl}`,
onSuccess: (data) => {
resolve(data);
},
onError: (error) => {
if (Axios.isAxiosError(error)) {
reject(error.response?.data)
} else {
reject(error)
}
},
});
})
return res.status(200).json(response);
} catch (error) {
return res.status(500).json(error);
}
});
/**
* Gitlab Authorization code
* -----------------------
*/
app.get("/oauth/gitlab", function (req, res) {
const state = Math.random().toString(36);
const stateCookieStr = serialize("oauth-v2-client-state", state, {
path: '/',
sameSite: 'lax',
priority: 'high',
maxAge: 60
})
res.setHeader('Set-Cookie', stateCookieStr)
res.redirect(gitlab.authorizationCode.getAuthUri({
state: state
}));
});
app.get("/gitlab/callback", async function (req, res) {
const cookie = parse(req.headers['cookie'] ?? '')
await gitlab.authorizationCode.getToken({
state: cookie["oauth-v2-client-state"],
callbackUrl: req.originalUrl,
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
});
});
app.post("/gitlab/refresh", async function (req, res) {
await gitlab.authorizationCode.refresh({
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
token: req.body
});
});
/**
* Bitbucket Authorization code
* -----------------------
*/
app.get("/oauth/bitbucket", function (req, res) {
res.redirect(bitbucket.authorizationCode.getAuthUri());
});
app.get("/bitbucket/callback", async function (req, res) {
await bitbucket.authorizationCode.getToken({
callbackUrl: req.originalUrl,
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
});
});
app.get("/bitbucket/refresh", async function (req, res) {
await bitbucket.authorizationCode.refresh({
onSuccess: (data) => {
res.status(200).json(data);
},
onError: (error) => {
res.status(500).json(error.response?.data);
},
token: req.body
});
});
app.get("/bitbucket/user", async function (req, res) {
await Axios.get(
"/2.0/user/emails",
bitbucket.authorizationCode.sign({
token: req.body
})
)
.then((response) => {
res.status(200).json(response.data);
})
.catch((error) => {
res.status(500).json(error);
});
});
/**
* Home
*/
app.get("/", function (req, res) {
res.json({
message: "Hey we there",
});
});
httpServer.listen(8080, () => {
console.log("started")
});