You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

191 lines
5.5 KiB

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:youtribe_lib/globals.dart' as globals;
class Api {
// Singleton
Api._privateConstructor();
static final Api _instance = Api._privateConstructor();
factory Api() {
return _instance;
}
Map<String, dynamic> credentials = {};
Map<String, String> apiHeaders = {
'Content-Type': 'application/json; charset=UTF-8'
};
int maxRetryCount = 2;
var client = http.Client();
void setHeaders(String jwt, String refreshToken, int expires) {
this.apiHeaders = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $jwt',
};
this.credentials = {
'jwt': jwt,
'refreshToken': refreshToken,
'expiresAt': expires >= 0
? new DateTime.now().add(new Duration(seconds: expires))
: new DateTime.now().add(new Duration(seconds: expires)),
};
}
Future<Map<dynamic, dynamic>> handleResponse(
Future<dynamic> response,
String path,
Map<dynamic, dynamic> body,
int tryCount,
Function(String path, Map<dynamic, dynamic> body, int tryCount)
callback) async {
return await response.then((res) {
var json = jsonDecode(res.body);
if (res.statusCode == 200) {
return json['data'];
} else {
if (tryCount < maxRetryCount) {
return callback(path, body, tryCount + 1);
} else {
return json;
}
}
}).catchError((err) {
if (tryCount < maxRetryCount) {
return callback(path, body, tryCount + 1);
} else {
globals.isApiReachabe = false;
return jsonDecode('{"code": 0, "message": "$err"}');
}
});
}
Future<Map<dynamic, dynamic>> post(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();
var res = client.post('${globals.apiUrl}$path',
headers: this.apiHeaders, body: body);
return await handleResponse(res, path, body, tryCount, post);
}
Future<Map<dynamic, dynamic>> patch(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
print("api patch");
await refreshJwt();
print("api after jwt");
var res = client.patch('${globals.apiUrl}$path',
headers: this.apiHeaders, body: jsonEncode(body));
return await handleResponse(res, path, body, tryCount, patch);
}
Future<Map<dynamic, dynamic>> get(String path,
[Map<dynamic, dynamic> body = const {}, int tryCount = 1]) async {
await refreshJwt();
var res = http.get(
'${globals.apiUrl}$path',
headers: this.apiHeaders,
);
return await handleResponse(res, path, body, tryCount, get);
}
Future<Map<dynamic, dynamic>> put(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();
var res = client.put('${globals.apiUrl}$path',
headers: this.apiHeaders, body: body);
return await handleResponse(res, path, body, tryCount, put);
}
Future<Map<dynamic, dynamic>> delete(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();
var res = client.delete(
'${globals.apiUrl}$path',
headers: this.apiHeaders,
);
return await handleResponse(res, path, body, tryCount, delete);
}
Future<Map<dynamic, dynamic>> authenticate(Map<String, String> body,
[int tryCount = 1]) async {
this.apiHeaders = {'Content-Type': 'application/json; charset=UTF-8'};
var res = await http
.post('${globals.apiUrl}/auth/login',
headers: this.apiHeaders, body: jsonEncode(body))
.then((res) {
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
setHeaders(json['data']['access_token'], json['data']['refresh_token'],
json['data']['expires']);
globals.isLoggedIn = true;
return {
"success": "logged in",
...json['data'],
};
} else {
if (tryCount < maxRetryCount) {
return authenticate(body, tryCount + 1);
} else {
return {"error": "http", "code": "${res.statusCode}"};
// return json;
}
}
}).catchError((err) {
if (tryCount <= maxRetryCount) {
return authenticate(body, tryCount + 1);
} else {
globals.isApiReachabe = false;
return {"error": err, "code": "000"};
}
});
return res;
}
Future<bool> refreshJwt() async {
if (!this.credentials.containsKey('expiresAt')) {
return false;
}
if (this.credentials['expiresAt'].isAfter(new DateTime.now())) {
return true;
} else {
var response = await http
.post('${globals.apiUrl}/auth/refresh',
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: jsonEncode(
{'refresh_token': this.credentials['refreshToken']}))
.then((res) {
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
setHeaders(json['data']['access_token'],
json['data']['refresh_token'], json['data']['expires']);
return true;
} else {
return false;
}
}).catchError((err) {
return false;
});
return response;
}
}
Future<bool> resumeSession(jwt, refreshToken) async {
this.setHeaders(jwt, refreshToken, -1000);
return await this.refreshJwt().then((res) {
return res;
}).catchError((err) {
return false;
});
}
}