start qr code
This commit is contained in:
parent
e5e77f264b
commit
5ee67927f6
27
containers/api/package-lock.json
generated
27
containers/api/package-lock.json
generated
@ -19,6 +19,8 @@
|
|||||||
"base32-decode": "^1.0.0",
|
"base32-decode": "^1.0.0",
|
||||||
"base32-encode": "^2.0.0",
|
"base32-encode": "^2.0.0",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
|
"hi-base32": "^0.5.1",
|
||||||
|
"nanoid": "^3.3.4",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@ -26,6 +28,7 @@
|
|||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
"thirty-two": "^1.0.2",
|
||||||
"typeorm": "^0.3.15",
|
"typeorm": "^0.3.15",
|
||||||
"webpack": "^5.82.0"
|
"webpack": "^5.82.0"
|
||||||
},
|
},
|
||||||
@ -4955,6 +4958,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hi-base32": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz",
|
||||||
|
"integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA=="
|
||||||
|
},
|
||||||
"node_modules/highlight.js": {
|
"node_modules/highlight.js": {
|
||||||
"version": "10.7.3",
|
"version": "10.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
|
||||||
@ -6457,6 +6465,17 @@
|
|||||||
"thenify-all": "^1.0.0"
|
"thenify-all": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -8296,6 +8315,14 @@
|
|||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/thirty-two": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.2.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/through": {
|
"node_modules/through": {
|
||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||||
|
|||||||
@ -30,6 +30,8 @@
|
|||||||
"base32-decode": "^1.0.0",
|
"base32-decode": "^1.0.0",
|
||||||
"base32-encode": "^2.0.0",
|
"base32-encode": "^2.0.0",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
|
"hi-base32": "^0.5.1",
|
||||||
|
"nanoid": "^3.3.4",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@ -37,6 +39,7 @@
|
|||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
"thirty-two": "^1.0.2",
|
||||||
"typeorm": "^0.3.15",
|
"typeorm": "^0.3.15",
|
||||||
"webpack": "^5.82.0"
|
"webpack": "^5.82.0"
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
containers/api/qrcode.png
Normal file
BIN
containers/api/qrcode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 767 B |
@ -1,6 +1,9 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import base32Decode from 'base32-decode';
|
import base32Decode from 'base32-decode';
|
||||||
|
|
||||||
|
// import { randomBytes} from 'crypto';
|
||||||
|
// import { promisify } from 'util';
|
||||||
|
|
||||||
// export function generateHOTP(secret, counter) {
|
// export function generateHOTP(secret, counter) {
|
||||||
// const decodedSecret = base32Decode(secret, 'RFC4648');
|
// const decodedSecret = base32Decode(secret, 'RFC4648');
|
||||||
|
|
||||||
@ -28,7 +31,7 @@ import base32Decode from 'base32-decode';
|
|||||||
// return `${code % 10 ** 6}`.padStart(6, '0');
|
// return `${code % 10 ** 6}`.padStart(6, '0');
|
||||||
// }
|
// }
|
||||||
|
|
||||||
type QRcode = any
|
// type QRcode = any;
|
||||||
|
|
||||||
export function generateHOTP(secret, counter) {
|
export function generateHOTP(secret, counter) {
|
||||||
const decodedSecret = base32Decode(secret, 'RFC4648');
|
const decodedSecret = base32Decode(secret, 'RFC4648');
|
||||||
@ -89,24 +92,40 @@ export function verifyTOTP(token, secret, window = 1)
|
|||||||
// import { Response } from 'express';
|
// import { Response } from 'express';
|
||||||
// import { Readable } from 'stream';
|
// import { Readable } from 'stream';
|
||||||
// import * as base32Encode from 'base32-encode';
|
// import * as base32Encode from 'base32-encode';
|
||||||
|
// import { base32Encode } from 'base32-encode';
|
||||||
|
// import base32Encode from 'base32-encode';
|
||||||
|
import { encode } from 'thirty-two';
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
import * as qrcode from 'qrcode';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
// import * as nanoid from 'nanoid'
|
||||||
|
|
||||||
export async function generateQRcode(req)
|
export async function generateQRcode(req)
|
||||||
{
|
{
|
||||||
// const base32Encode = await import('base32-encode');
|
// const base32Encode = (await import('base32-encode'));
|
||||||
const base32Encode = (await import('base32-encode'));
|
// const nanoid = (await import('nanoid'));
|
||||||
const util = (await import('util'));
|
|
||||||
const qrcode = (await import('qrcode'));
|
// const util = (await import('util'));
|
||||||
|
// const qrcode = (await import('qrcode'));
|
||||||
|
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
let res: QRcode;
|
let res;
|
||||||
// For security, we no longer show the QR code after is verified
|
// For security, we no longer show the QR code after is verified
|
||||||
// if (user.mfaEnabled) return res.status(404).end();
|
// if (user.mfaEnabled) return res.status(404).end();
|
||||||
|
|
||||||
// if (!user.mfaSecret) { //to do
|
// if (!user.mfaSecret) { //to do
|
||||||
|
const buffer = nanoid(14);
|
||||||
// generate unique secret for user
|
// generate unique secret for user
|
||||||
// this secret will be used to check the verification code sent by user
|
// this secret will be used to check the verification code sent by user
|
||||||
const buffer = await util.promisify(crypto.randomBytes)(14);
|
// const buffer = await util.promisify(crypto.randomBytes)(14);
|
||||||
user.mfaSecret = base32Encode(buffer, 'RFC4648', { padding: false });
|
// const buffer = crypto.lib.WordArray.random(32)
|
||||||
|
user.mfaSecret = encode(buffer).toString('utf8');
|
||||||
|
// user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
|
||||||
|
|
||||||
// setUser(user); // to do !!
|
// setUser(user); // to do !!
|
||||||
|
|
||||||
@ -121,8 +140,40 @@ export async function generateQRcode(req)
|
|||||||
const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
||||||
|
|
||||||
// res.setHeader('Content-Type', 'image/png');
|
// res.setHeader('Content-Type', 'image/png');
|
||||||
|
const QRCode = require('qrcode');
|
||||||
|
console.log(`before done`);
|
||||||
|
// QRCode.toFileStream(res, configUri);
|
||||||
|
// const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||||
|
|
||||||
qrcode.toFileStream(res, configUri);
|
|
||||||
|
const qrCodeData = buffer; // Replace with your actual QR code data
|
||||||
|
const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||||
|
|
||||||
|
qrcode.toFile(filePath, qrCodeData, (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
// Handle the error appropriately
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// QR code image has been generated and saved to the file
|
||||||
|
// Or, you can create a buffer of the image data directly
|
||||||
|
})
|
||||||
|
|
||||||
|
// qrcode.toFile(filePath, configUri, (error) => {
|
||||||
|
// if (error) {
|
||||||
|
// console.error(error);
|
||||||
|
// // Handle the error appropriately
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// const readableStream = fs.createReadStream(filePath);
|
||||||
|
// res.data = readableStream;
|
||||||
|
// Use the readable stream as needed
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// qrcode.toFileStream(res, configUri);
|
||||||
console.log(`QRcode done`);
|
console.log(`QRcode done`);
|
||||||
return res;
|
return res;
|
||||||
|
// return
|
||||||
}
|
}
|
||||||
@ -1,81 +1,146 @@
|
|||||||
import React, { useCallback, useState, useEffect } from 'react';
|
import React, { useCallback, useState, useEffect } from 'react';
|
||||||
import api from '../script/axiosApi';
|
import api from '../script/axiosApi';
|
||||||
|
|
||||||
function DoubleAuth() {
|
// function DoubleAuth() {
|
||||||
|
|
||||||
// const enabled = await api.get("/2fa");
|
// // const enabled = await api.get("/2fa");
|
||||||
|
|
||||||
// const response = await api.get("/2fa");
|
// // const response = await api.get("/2fa");
|
||||||
// const enabled = response.data;
|
// // const enabled = response.data;
|
||||||
// console.log(`enable= ${enabled.data}`)
|
// // console.log(`enable= ${enabled.data}`)
|
||||||
// const enabled = 0;
|
// // const enabled = 0;
|
||||||
let enabled;
|
// let enabled;
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// async function get2fa()
|
||||||
|
// {
|
||||||
|
// const response = await api.get("/2fa");
|
||||||
|
// const enabled = response.data;
|
||||||
|
// console.log(`enable= ${enabled.data}`)
|
||||||
|
// }
|
||||||
|
// // const enabled = 0;
|
||||||
|
// }, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// async function get2fa()
|
||||||
|
// {
|
||||||
|
// api.get('/api/QRcode', { responseType: 'blob' })
|
||||||
|
// .then(response => {
|
||||||
|
// const reader = new FileReader();
|
||||||
|
// reader.onloadend = () => {
|
||||||
|
// setImageSrc(reader.result);
|
||||||
|
// };
|
||||||
|
// reader.readAsDataURL(response.data);
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.error(error);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// } }, []);
|
||||||
|
|
||||||
|
// // const [verificationCode, setVerificationCode] = useState('');
|
||||||
|
// // const [invalidCode, setInvalidCode] = useState(false);
|
||||||
|
|
||||||
|
// const handleSubmit = () => {
|
||||||
|
// // async (e) => {
|
||||||
|
// // e.preventDefault();
|
||||||
|
|
||||||
|
// // const result = await verifyOtp(verificationCode);
|
||||||
|
|
||||||
|
// // if (result) return (window.location = '/');
|
||||||
|
|
||||||
|
// // setInvalidCode(true);
|
||||||
|
// // },
|
||||||
|
// // [verificationCode]
|
||||||
|
// };
|
||||||
|
|
||||||
|
// let sourceCode
|
||||||
|
|
||||||
|
// if (!enabled)
|
||||||
|
// {
|
||||||
|
// api.get('/QRcode')
|
||||||
|
// .then(response => {
|
||||||
|
// sourceCode = response.data;
|
||||||
|
// console.log(sourceCode);
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.error(error);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div>
|
||||||
|
// {!enabled && (
|
||||||
|
// <div>
|
||||||
|
// <p>Scan the QR code on your authenticator app</p>
|
||||||
|
// <img src={sourceCode} />
|
||||||
|
// </div>
|
||||||
|
// )}
|
||||||
|
|
||||||
|
// <form onSubmit={handleSubmit}>
|
||||||
|
// {/* <Input
|
||||||
|
// id="verificationCode"
|
||||||
|
// label="Verification code"
|
||||||
|
// type="text"
|
||||||
|
// value={verificationCode}
|
||||||
|
// onChange={(e) => setVerificationCode(e.target.value)}
|
||||||
|
// /> */}
|
||||||
|
|
||||||
|
// <button type="submit">Confirm</button>
|
||||||
|
|
||||||
|
// {/* {invalidCode && <p>Invalid verification code</p>} */}
|
||||||
|
// </form>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// import { toFileStream } from 'qrcode';
|
||||||
|
|
||||||
|
const DoubleAuth = () => {
|
||||||
|
const [imageSrc, setImageSrc] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function get2fa()
|
async function getCode(){
|
||||||
{
|
await api.get('/QRcode', { responseType: 'blob' })
|
||||||
const response = await api.get("/2fa");
|
.then(response => {
|
||||||
const enabled = response.data;
|
const reader = new FileReader();
|
||||||
console.log(`enable= ${enabled.data}`)
|
reader.onloadend = () => {
|
||||||
}
|
setImageSrc(reader.result);
|
||||||
// const enabled = 0;
|
};
|
||||||
}, [])
|
reader.readAsDataURL(response.data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
// const [verificationCode, setVerificationCode] = useState('');
|
console.error(error);
|
||||||
// const [invalidCode, setInvalidCode] = useState(false);
|
});
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
// async (e) => {
|
|
||||||
// e.preventDefault();
|
|
||||||
|
|
||||||
// const result = await verifyOtp(verificationCode);
|
|
||||||
|
|
||||||
// if (result) return (window.location = '/');
|
|
||||||
|
|
||||||
// setInvalidCode(true);
|
|
||||||
// },
|
|
||||||
// [verificationCode]
|
|
||||||
};
|
|
||||||
|
|
||||||
let sourceCode
|
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
{
|
|
||||||
api.get('/QRcode')
|
|
||||||
.then(response => {
|
|
||||||
sourceCode = response.data;
|
|
||||||
console.log(sourceCode);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
getCode();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<div>
|
// <div>
|
||||||
{!enabled && (
|
// {imageSrc && <img src={imageSrc} alt="QR Code" />}
|
||||||
<div>
|
// </div>
|
||||||
<p>Scan the QR code on your authenticator app</p>
|
// );
|
||||||
<img src={sourceCode} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<form onSubmit={handleSubmit}>
|
// <img src={sourceCode} />
|
||||||
{/* <Input
|
|
||||||
id="verificationCode"
|
|
||||||
label="Verification code"
|
|
||||||
type="text"
|
|
||||||
value={verificationCode}
|
|
||||||
onChange={(e) => setVerificationCode(e.target.value)}
|
|
||||||
/> */}
|
|
||||||
|
|
||||||
<button type="submit">Confirm</button>
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<p>Scan the QR code on your authenticator app</p>
|
||||||
|
{imageSrc && <img src={imageSrc} alt="QR Code" />}
|
||||||
|
</div>
|
||||||
|
{/* <form onSubmit={handleSubmit}>
|
||||||
|
<button type="submit">Confirm</button>
|
||||||
|
</form> */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
{/* {invalidCode && <p>Invalid verification code</p>} */}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DoubleAuth;
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default DoubleAuth;
|
||||||
@ -386,11 +386,11 @@ requestAnimationFrame(draw);
|
|||||||
vY = -vY;
|
vY = -vY;
|
||||||
// send_info();
|
// send_info();
|
||||||
}
|
}
|
||||||
else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
||||||
{
|
// {
|
||||||
vX = -vX;
|
// vX = -vX;
|
||||||
// send_info();
|
// // send_info();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_out()
|
function is_out()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user