Skip to content

Commit 6faba1f

Browse files
committed
Fetch powersync keys
1 parent fe48597 commit 6faba1f

File tree

13 files changed

+202
-105
lines changed

13 files changed

+202
-105
lines changed

Gemfile.lock

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ GEM
55
base64
66
nkf
77
rexml
8-
addressable (2.8.6)
9-
public_suffix (>= 2.0.2, < 6.0)
8+
addressable (2.8.7)
9+
public_suffix (>= 2.0.2, < 7.0)
1010
artifactory (3.0.17)
1111
atomos (0.1.3)
1212
aws-eventstream (1.3.0)
13-
aws-partitions (1.944.0)
14-
aws-sdk-core (3.197.0)
13+
aws-partitions (1.960.0)
14+
aws-sdk-core (3.201.3)
1515
aws-eventstream (~> 1, >= 1.3.0)
1616
aws-partitions (~> 1, >= 1.651.0)
1717
aws-sigv4 (~> 1.8)
1818
jmespath (~> 1, >= 1.6.1)
19-
aws-sdk-kms (1.84.0)
20-
aws-sdk-core (~> 3, >= 3.197.0)
21-
aws-sigv4 (~> 1.1)
22-
aws-sdk-s3 (1.152.3)
23-
aws-sdk-core (~> 3, >= 3.197.0)
19+
aws-sdk-kms (1.88.0)
20+
aws-sdk-core (~> 3, >= 3.201.0)
21+
aws-sigv4 (~> 1.5)
22+
aws-sdk-s3 (1.156.0)
23+
aws-sdk-core (~> 3, >= 3.201.0)
2424
aws-sdk-kms (~> 1)
25-
aws-sigv4 (~> 1.8)
26-
aws-sigv4 (1.8.0)
25+
aws-sigv4 (~> 1.5)
26+
aws-sigv4 (1.9.1)
2727
aws-eventstream (~> 1, >= 1.0.2)
2828
babosa (1.0.4)
2929
base64 (0.2.0)
@@ -38,7 +38,7 @@ GEM
3838
domain_name (0.6.20240107)
3939
dotenv (2.8.1)
4040
emoji_regex (3.2.3)
41-
excon (0.110.0)
41+
excon (0.111.0)
4242
faraday (1.10.3)
4343
faraday-em_http (~> 1.0)
4444
faraday-em_synchrony (~> 1.0)
@@ -60,15 +60,15 @@ GEM
6060
faraday-httpclient (1.0.1)
6161
faraday-multipart (1.0.4)
6262
multipart-post (~> 2)
63-
faraday-net_http (1.0.1)
63+
faraday-net_http (1.0.2)
6464
faraday-net_http_persistent (1.2.0)
6565
faraday-patron (1.0.0)
6666
faraday-rack (1.0.0)
6767
faraday-retry (1.0.3)
6868
faraday_middleware (1.2.0)
6969
faraday (~> 1.0)
7070
fastimage (2.3.1)
71-
fastlane (2.220.0)
71+
fastlane (2.222.0)
7272
CFPropertyList (>= 2.3, < 4.0.0)
7373
addressable (>= 2.8, < 3.0.0)
7474
artifactory (~> 3.0)
@@ -153,9 +153,9 @@ GEM
153153
httpclient (2.8.3)
154154
jmespath (1.6.2)
155155
json (2.7.2)
156-
jwt (2.8.1)
156+
jwt (2.8.2)
157157
base64
158-
mini_magick (4.13.1)
158+
mini_magick (4.13.2)
159159
mini_mime (1.1.5)
160160
multi_json (1.15.0)
161161
multipart-post (2.4.1)
@@ -165,7 +165,7 @@ GEM
165165
optparse (0.5.0)
166166
os (1.1.4)
167167
plist (3.7.1)
168-
public_suffix (5.1.0)
168+
public_suffix (6.0.1)
169169
rake (13.2.1)
170170
representable (3.2.0)
171171
declarative (< 0.1.0)

fastlane/report.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66

77

8-
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000214">
8+
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000258">
99

1010
</testcase>
1111

1212

13-
<testcase classname="fastlane.lanes" name="1: upload_to_play_store" time="167.371876">
13+
<testcase classname="fastlane.lanes" name="1: upload_to_play_store" time="178.169255">
1414

1515
</testcase>
1616

lib/api_client.dart

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,87 @@
11
import 'dart:convert';
2+
import 'dart:io';
3+
24
import 'package:http/http.dart' as http;
35
import 'package:logging/logging.dart';
6+
import 'package:shared_preferences/shared_preferences.dart';
7+
8+
import 'helpers/consts.dart';
49

510
final log = Logger('powersync-test');
611

712
class ApiClient {
813
final String baseUrl;
914

10-
ApiClient(this.baseUrl);
15+
const ApiClient(this.baseUrl);
1116

1217
Future<Map<String, dynamic>> authenticate(String username, String password) async {
1318
final response = await http.post(
14-
Uri.parse('$baseUrl/api/auth/'),
19+
Uri.parse('$baseUrl/api/v2/login/'),
1520
headers: {'Content-Type': 'application/json'},
1621
body: json.encode({'username': username, 'password': password}),
1722
);
1823
if (response.statusCode == 200) {
24+
log.log(Level.ALL, response.body);
1925
return json.decode(response.body);
20-
} else {
21-
throw Exception('Failed to authenticate');
2226
}
27+
throw Exception('Failed to authenticate');
2328
}
2429

25-
Future<Map<String, dynamic>> getToken(String userId) async {
30+
Future<Map<String, dynamic>> getWgerJWTToken() async {
31+
final response = await http.post(
32+
Uri.parse('$baseUrl/api/v2/token'),
33+
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
34+
body: json.encode({'username': 'admin', 'password': 'adminadmin'}),
35+
);
36+
if (response.statusCode == 200) {
37+
log.log(Level.ALL, response.body);
38+
return json.decode(response.body);
39+
}
40+
throw Exception('Failed to fetch token');
41+
}
42+
43+
/// Returns a powersync JWT token token
44+
///
45+
/// Note that at the moment we use the permanent API token for authentication
46+
/// but this should be probably changed to the wger API JWT tokens in the
47+
/// future since they are not permanent and could be easily revoked.
48+
Future<Map<String, dynamic>> getPowersyncToken() async {
49+
final prefs = await SharedPreferences.getInstance();
50+
final apiData = json.decode(prefs.getString(PREFS_USER)!);
51+
2652
final response = await http.get(
27-
Uri.parse('$baseUrl/api/get_powersync_token/'),
28-
headers: {'Content-Type': 'application/json'},
53+
Uri.parse('$baseUrl/api/v2/powersync-token'),
54+
headers: {
55+
HttpHeaders.contentTypeHeader: 'application/json',
56+
HttpHeaders.authorizationHeader: 'Token ${apiData["token"]}',
57+
},
2958
);
3059
if (response.statusCode == 200) {
60+
log.log(Level.ALL, response.body);
3161
return json.decode(response.body);
32-
} else {
33-
throw Exception('Failed to fetch token');
3462
}
63+
throw Exception('Failed to fetch token');
3564
}
3665

3766
Future<void> upsert(Map<String, dynamic> record) async {
3867
await http.put(
39-
Uri.parse('$baseUrl/api/upload_data/'),
68+
Uri.parse('$baseUrl/api/upload-powersync-data'),
4069
headers: {'Content-Type': 'application/json'},
4170
body: json.encode(record),
4271
);
4372
}
4473

4574
Future<void> update(Map<String, dynamic> record) async {
4675
await http.patch(
47-
Uri.parse('$baseUrl/api/upload_data/'),
76+
Uri.parse('$baseUrl/api/upload-powersync-data'),
4877
headers: {'Content-Type': 'application/json'},
4978
body: json.encode(record),
5079
);
5180
}
5281

5382
Future<void> delete(Map<String, dynamic> record) async {
5483
await http.delete(
55-
Uri.parse('$baseUrl/api/upload_data/'),
84+
Uri.parse('$baseUrl/api/v2/upload-powersync-data'),
5685
headers: {'Content-Type': 'application/json'},
5786
body: json.encode(record),
5887
);

lib/app_config.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
class AppConfig {
2-
static const String djangoUrl = 'http://192.168.2.223:6061';
3-
static const String powersyncUrl = 'http://192.168.2.223:8080';
2+
static const String djangoUrl = 'http://10.0.2.2:8000';
3+
static const String powersyncUrl = 'http://10.0.2.2:8080';
44
}

lib/models/muscle.dart

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:powersync/sqlite3.dart' as sqlite;
2+
import 'package:wger/models/schema.dart';
3+
import 'package:wger/powersync.dart';
4+
5+
class Muscle {
6+
final String id;
7+
final String name;
8+
final String nameEn;
9+
final bool isFront;
10+
11+
const Muscle({
12+
required this.id,
13+
required this.name,
14+
required this.nameEn,
15+
required this.isFront,
16+
});
17+
18+
factory Muscle.fromRow(sqlite.Row row) {
19+
return Muscle(
20+
id: row['id'],
21+
name: row['name'],
22+
nameEn: row['name_en'],
23+
isFront: row['is_front'] == 1,
24+
);
25+
}
26+
27+
Future<void> delete() async {
28+
await db.execute('DELETE FROM $musclesTable WHERE id = ?', [id]);
29+
}
30+
31+
/// Watch all lists.
32+
static Stream<List<Muscle>> watchMuscles() {
33+
return db.watch('SELECT * FROM muscles ORDER BY id').map((results) {
34+
return results.map(Muscle.fromRow).toList(growable: false);
35+
});
36+
}
37+
}

lib/models/schema.dart

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
11
import 'package:powersync/powersync.dart';
22

33
const todosTable = 'todos';
4+
const musclesTable = 'muscles';
45

56
// these are the same ones as in postgres, except for 'id'
6-
Schema schema = const Schema(([
7-
Table(todosTable, [
8-
Column.text('list_id'),
9-
Column.text('created_at'),
10-
Column.text('completed_at'),
11-
Column.text('description'),
12-
Column.integer('completed'),
13-
Column.text('created_by'),
14-
Column.text('completed_by'),
15-
], indexes: [
16-
// Index to allow efficient lookup within a list
17-
Index('list', [IndexedColumn('list_id')])
18-
]),
19-
Table('lists',
20-
[Column.text('created_at'), Column.text('name'), Column.text('owner_id')])
21-
]));
7+
Schema schema = const Schema([
8+
Table(
9+
todosTable,
10+
[
11+
Column.text('list_id'),
12+
Column.text('created_at'),
13+
Column.text('completed_at'),
14+
Column.text('description'),
15+
Column.integer('completed'),
16+
Column.text('created_by'),
17+
Column.text('completed_by'),
18+
],
19+
indexes: [
20+
// Index to allow efficient lookup within a list
21+
Index('list', [IndexedColumn('list_id')]),
22+
],
23+
),
24+
Table(
25+
'lists',
26+
[
27+
Column.text('created_at'),
28+
Column.text('name'),
29+
Column.text('owner_id'),
30+
],
31+
),
32+
Table(
33+
'muscles',
34+
[
35+
Column.text('name'),
36+
Column.text('name_en'),
37+
Column.text('is_front'),
38+
],
39+
),
40+
]);
2241

2342
// post gres columns:
2443
// todos:

lib/models/todo_item.dart

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import 'package:wger/models/schema.dart';
2-
3-
import '../powersync.dart';
41
import 'package:powersync/sqlite3.dart' as sqlite;
2+
import 'package:wger/models/schema.dart';
3+
import 'package:wger/powersync.dart';
54

65
/// TodoItem represents a result row of a query on "todos".
76
///
@@ -14,18 +13,20 @@ class TodoItem {
1413
final String? photoId;
1514
final bool completed;
1615

17-
TodoItem(
18-
{required this.id,
19-
required this.description,
20-
required this.completed,
21-
required this.photoId});
16+
TodoItem({
17+
required this.id,
18+
required this.description,
19+
required this.completed,
20+
required this.photoId,
21+
});
2222

2323
factory TodoItem.fromRow(sqlite.Row row) {
2424
return TodoItem(
25-
id: row['id'],
26-
description: row['description'],
27-
photoId: row['photo_id'],
28-
completed: row['completed'] == 1);
25+
id: row['id'],
26+
description: row['description'],
27+
photoId: row['photo_id'],
28+
completed: row['completed'] == 1,
29+
);
2930
}
3031

3132
Future<void> toggle() async {

lib/models/todo_list.dart

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:powersync/sqlite3.dart' as sqlite;
2+
import 'package:wger/powersync.dart';
23

34
import 'todo_item.dart';
4-
import '../powersync.dart';
55

66
/// TodoList represents a result row of a query on "lists".
77
///
@@ -24,10 +24,11 @@ class TodoList {
2424

2525
factory TodoList.fromRow(sqlite.Row row) {
2626
return TodoList(
27-
id: row['id'],
28-
name: row['name'],
29-
completedCount: row['completed_count'],
30-
pendingCount: row['pending_count']);
27+
id: row['id'],
28+
name: row['name'],
29+
completedCount: row['completed_count'],
30+
pendingCount: row['pending_count'],
31+
);
3132
}
3233

3334
/// Watch all lists.
@@ -55,12 +56,15 @@ class TodoList {
5556

5657
/// Create a new list
5758
static Future<TodoList> create(String name) async {
58-
final results = await db.execute('''
59+
final results = await db.execute(
60+
'''
5961
INSERT INTO
6062
lists(id, created_at, name, owner_id)
6163
VALUES(uuid(), datetime(), ?, ?)
6264
RETURNING *
63-
''', [name, await getUserId()]);
65+
''',
66+
[name, await getUserId()],
67+
);
6468
return TodoList.fromRow(results.first);
6569
}
6670

0 commit comments

Comments
 (0)