Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion .github/workflows/analyze.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ jobs:
dart pub get --directory=example_flutter
fi
- run: dart analyze --fatal-infos
- run: dart format --output=none --set-exit-if-changed .
- run: dart pub publish --dry-run
- run: |
- name: Pana
if: hashFiles(format('{0}/pubspec_overrides.yaml', matrix.package)) == ''
run: |
dart pub global activate pana
pana --no-warning --exit-code-threshold 0
40 changes: 17 additions & 23 deletions vrchat_dart/lib/src/api/src/auth_api.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:convert';

import 'package:dio_response_validator/dio_response_validator.dart';
import 'package:vrchat_dart_generated/vrchat_dart_generated.dart';
import 'package:vrchat_dart/src/convenience/user_extensions.dart';
import 'package:vrchat_dart/src/model/api/vrc_response.dart';

/// Auth convenience methods
Expand Down Expand Up @@ -34,31 +36,23 @@ class AuthApi {
.validateVrc();

if (success != null) {
_currentUser = success.data;
return (ValidResponse(AuthResponse(), success.response), null);
} else if (failure != null) {
final response = failure.response;
if (response == null) return (null, failure);

final data = response.data;
if (data is! Map<String, dynamic>) return (null, failure);
final twoFactorAuthTypes = success.data.requiresTwoFactorAuth;
if (twoFactorAuthTypes != null && twoFactorAuthTypes.isNotEmpty) {
return (
ValidResponse(
AuthResponse(twoFactorAuthTypes: twoFactorAuthTypes),
success.response,
),
null,
);
}

final twoFactorAuthTypes = (data['requiresTwoFactorAuth'] as List?)
?.cast<String>()
.map(TwoFactorAuthType.values.byName)
.toList();
if (twoFactorAuthTypes == null) return (null, failure);

return (
ValidResponse(
AuthResponse(twoFactorAuthTypes: twoFactorAuthTypes),
response,
),
null,
);
} else {
throw StateError('This should never happen');
_currentUser = success.data.toCurrentUser();
return (ValidResponse(AuthResponse(), success.response), null);
}

if (failure == null) throw StateError('This should never happen');
return (null, failure);
}

/// Verify a 2fa code
Expand Down
33 changes: 33 additions & 0 deletions vrchat_dart/lib/src/convenience/user_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ extension UserExtension on User {
}
}

/// Convenience methods on [CurrentUserLoginResponse]
extension CurrentUserLoginResponseExtension on CurrentUserLoginResponse {
/// Convert a [CurrentUserLoginResponse] to a [CurrentUser]
CurrentUser toCurrentUser() {
return CurrentUser.fromJson({
...toJson(),
'last_mobile': lastMobile?.toIso8601String(),
});
}
}

/// Convenience methods on [UserResponse]
extension UserResponseExtension on UserResponse {
/// Convert a [UserResponse] to a [User]
User toUser() {
return User.fromJson(toJson());
}

/// Convert a [UserResponse] to a [CurrentUser]
CurrentUser toCurrentUser() {
return CurrentUser.fromJson({...toJson(), 'last_mobile': lastMobile});
}

/// Convert a [UserResponse] to a [LimitedUser]
LimitedUser toLimitedUser() {
return LimitedUser.fromJson({
...toJson(),
'last_login': DateTime.tryParse(lastLogin)?.toIso8601String(),
'last_activity': DateTime.tryParse(lastActivity ?? '')?.toIso8601String(),
});
}
}

/// Convenience methods on [LimitedUserInstance]
extension LimitedUserInstanceExtension on LimitedUserInstance {
/// Convert a [LimitedUserInstance] to a [LimitedUser]
Expand Down
13 changes: 1 addition & 12 deletions vrchat_dart/lib/src/model/api/vrc_response.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:dio/dio.dart';
import 'package:dio_response_validator/dio_response_validator.dart';
import 'package:meta/meta.dart';
import 'package:vrchat_dart_generated/vrchat_dart_generated.dart' hide Response;

/// A response from the auth API
@immutable
Expand All @@ -16,18 +17,6 @@ class AuthResponse {
: requiresTwoFactorAuth = twoFactorAuthTypes.isNotEmpty;
}

/// Types of two factor auth for VRChat
enum TwoFactorAuthType {
/// One time password (probably a backup code)
otp,

/// Timed one time password from an authenticator app
totp,

/// Two factor auth via an email
emailOtp,
}

/// An error returned from the VRChat API
@immutable
class VrcError {
Expand Down
2 changes: 1 addition & 1 deletion vrchat_dart/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ environment:
sdk: ^3.8.0

dependencies:
vrchat_dart_generated: ^1.20.0
vrchat_dart_generated: ^1.22.0
dio_cookie_manager: ^3.0.0
cookie_jar: ^4.0.1
dio: ^5.2.0
Expand Down
3 changes: 3 additions & 0 deletions vrchat_dart/pubspec_overrides.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependency_overrides:
vrchat_dart_generated:
path: ../vrchat_dart_generated
Loading
Loading