finish off login
This commit is contained in:
parent
754bfa8ef0
commit
601b13feb6
|
@ -251,6 +251,9 @@ class UserLogin(APIView):
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def post(self, req: HttpRequest):
|
def post(self, req: HttpRequest):
|
||||||
|
|
||||||
|
# for debug purposes
|
||||||
|
# return HttpResponse("""{"user_data": {"id": 1, "name": "\u041d\u0438\u043a\u0438\u0442\u0430 \u041f\u0443\u0441\u0442\u043e\u0432\u0430\u043b\u043e\u0432", "date_of_birth": null, "about_me": "", "gender": "?", "phone": "+00000", "email": null, "telegram": null, "discord": null, "city": null, "role": "s", "photo_provider": "VVSU", "openid_addr": "blek__@vvsu.ru", "openid_id": "096C78CD-4943-4D57-BC6D-5CDE12F686E3"}, "new_user": false, "token": {"id": 2, "user": 1, "key": "e1c24581-523a-4f60-973f-02ba873b3edc", "expires": 1684423572, "ip": "127.0.0.1"}}""");
|
||||||
|
|
||||||
if (req.session.has_key('auth_data')):
|
if (req.session.has_key('auth_data')):
|
||||||
# TODO: Return user object instead of error
|
# TODO: Return user object instead of error
|
||||||
return JsonResponse({'error': 'already authenticated'})
|
return JsonResponse({'error': 'already authenticated'})
|
||||||
|
|
|
@ -21,30 +21,44 @@ class IAPIObject {
|
||||||
*/
|
*/
|
||||||
static storage_key = undefined;
|
static storage_key = undefined;
|
||||||
|
|
||||||
/** @returns {ThisType} */
|
static _checkStorageSupport() {
|
||||||
static restoreFromLocalStorage() {
|
if (storage_key === undefined) {
|
||||||
if (storage_key !== undefined) {
|
|
||||||
throw Error('This doesn\'t support local storage');
|
throw Error('This doesn\'t support local storage');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_getStorageKey() {
|
||||||
|
return Object.getPrototypeOf(this).constructor.storage_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
_IcheckStorageSupport() {
|
||||||
|
if (this._getStorageKey() === undefined) {
|
||||||
|
throw Error('This doesn\'t support local storage');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {ThisType} */
|
||||||
|
static restoreFromLocalStorage() {
|
||||||
|
_checkStorageSupport();
|
||||||
if (!window.localStorage.getItem(storage_key))
|
if (!window.localStorage.getItem(storage_key))
|
||||||
return false;
|
return false;
|
||||||
return new APIToken(window.localStorage.getItem(storage_key));
|
return new APIToken(window.localStorage.getItem(storage_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} */
|
||||||
|
static isCached() {
|
||||||
|
_checkStorageSupport();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save this object to local storage
|
* Save this object to local storage
|
||||||
* @throws {QuotaExceededError}
|
* @throws {QuotaExceededError}
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
saveToLocalStorage() {
|
saveToLocalStorage() {
|
||||||
|
this._IcheckStorageSupport();
|
||||||
|
|
||||||
// static this
|
window.localStorage.setItem(this._getStorageKey(), JSON.stringify(this));
|
||||||
sthis = Object.getPrototypeOf(this);
|
|
||||||
|
|
||||||
if (sthis.storage_key !== undefined) {
|
|
||||||
throw Error('This doesn\'t support local storage');
|
|
||||||
}
|
|
||||||
window.localStorage.setItem(sthis.storage_key, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +67,7 @@ class APIToken extends IAPIObject {
|
||||||
static storage_key = 'pairent_api_key';
|
static storage_key = 'pairent_api_key';
|
||||||
|
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
|
super();
|
||||||
this.user = data.user;
|
this.user = data.user;
|
||||||
this.key = data.key;
|
this.key = data.key;
|
||||||
this.expires = data.expires;
|
this.expires = data.expires;
|
||||||
|
@ -76,9 +91,14 @@ class APIToken extends IAPIObject {
|
||||||
|
|
||||||
class User extends IAPIObject {
|
class User extends IAPIObject {
|
||||||
|
|
||||||
|
isLoggedIn() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static storage_key = 'pairent_user_data';
|
static storage_key = 'pairent_user_data';
|
||||||
|
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
|
super();
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
this[key] = data[key];
|
this[key] = data[key];
|
||||||
}
|
}
|
||||||
|
@ -107,9 +127,14 @@ class User extends IAPIObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await axios.post(api_path('/api/auth/user/login'), response);
|
const data = await axios.post(api_path('/api/auth/user/login'), response);
|
||||||
|
if (data.status !== 200) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
window.localStorage.setItem(APIToken.storage_key, data.data.token);
|
if (!data.data.error) {
|
||||||
window.localStorage.setItem(User.storage_key, data.data.user_data);
|
new APIToken(data.data.token).saveToLocalStorage();
|
||||||
|
new User(data.data.user_data).saveToLocalStorage();
|
||||||
|
}
|
||||||
|
|
||||||
return data.data;
|
return data.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { HashLoader } from "react-spinners";
|
||||||
import { SigninResponse, UserManager } from 'oidc-client-ts';
|
import { SigninResponse, UserManager } from 'oidc-client-ts';
|
||||||
import { User } from "../../API/User";
|
import { User } from "../../API/User";
|
||||||
import FloatingBox from "../../components/UI/FloatingBox";
|
import FloatingBox from "../../components/UI/FloatingBox";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
|
|
||||||
import constants from "../../constants";
|
import constants from "../../constants";
|
||||||
|
|
||||||
|
@ -33,12 +32,12 @@ export default class LoggedIn extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.response = new SigninResponse(new URL(window.location.href).searchParams);
|
this.response = new SigninResponse(new URL(window.location.href).searchParams);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
if (this.response.error) return;
|
if (this.response.error) return;
|
||||||
|
window.localStorage.removeItem('auth_fail');
|
||||||
|
|
||||||
let code_verifier = '?';
|
let code_verifier = '?';
|
||||||
// get code verifier
|
// get code verifier
|
||||||
for (const key in localStorage) {
|
for (const key in localStorage) {
|
||||||
|
@ -50,11 +49,19 @@ export default class LoggedIn extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await User.login({...this.response, code_verifier});
|
const response = await User.login({...this.response, code_verifier});
|
||||||
|
|
||||||
|
if (response.error) {
|
||||||
|
// pass the data to LoginPage
|
||||||
|
window.localStorage.setItem('auth_fail', JSON.stringify(response));
|
||||||
|
window.location.href = '/login';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.new_user) {
|
if (response.new_user) {
|
||||||
// TODO: Make the page
|
// TODO: Make the page
|
||||||
useNavigate('/register');
|
window.location.href = '/register';
|
||||||
} else {
|
} else {
|
||||||
useNavigate('/');
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,11 @@ export default class LoginPage extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false
|
loading: false,
|
||||||
|
error: JSON.parse(window.localStorage.getItem('auth_fail'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.localStorage.removeItem('auth_fail');
|
||||||
this.openid = this.openid.bind(this);
|
this.openid = this.openid.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +58,11 @@ export default class LoginPage extends React.Component {
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
|
|
||||||
OpenID.Log.setLogger(console);
|
OpenID.Log.setLogger(console);
|
||||||
OpenID.Log.setLevel(OpenID.Log.DEBUG);
|
OpenID.Log.setLevel(OpenID.Log.NONE);
|
||||||
|
|
||||||
let client = new OpenID.UserManager(OIDCConfig);
|
let client = new OpenID.UserManager(OIDCConfig);
|
||||||
|
|
||||||
client.signinRedirect();
|
client.signinRedirect();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -84,6 +85,21 @@ export default class LoginPage extends React.Component {
|
||||||
Вход осуществляется только через<br/>
|
Вход осуществляется только через<br/>
|
||||||
Систему Единого Входа ВВГУ
|
Систему Единого Входа ВВГУ
|
||||||
</SmallText>
|
</SmallText>
|
||||||
|
{
|
||||||
|
this.state.error ?
|
||||||
|
<SmallText style={{color: 'darkred', fontWeight: '600'}}>
|
||||||
|
Произошла ошибка: { this.state.error.error }
|
||||||
|
{
|
||||||
|
this.state.error.error_description ?
|
||||||
|
<>
|
||||||
|
<br/>
|
||||||
|
{this.state.error.error_description}
|
||||||
|
</>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</SmallText>
|
||||||
|
: null
|
||||||
|
}
|
||||||
</FloatingBox>
|
</FloatingBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue