Page MenuHomePhorge

D5649.1775243621.diff
No OneTemporary

Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None

D5649.1775243621.diff

diff --git a/src/app/Device.php b/src/app/Device.php
--- a/src/app/Device.php
+++ b/src/app/Device.php
@@ -126,8 +126,24 @@
{
DB::beginTransaction();
- // Create a device record
- $device = self::create(['hash' => $token]);
+ // Check if a device already exists
+ $device = Device::withTrashed()->where('hash', $token)->first();
+
+ if ($device) {
+ // FIXME: Should we remove the user (if it's a role=device user)?
+ // FIXME: Should we bail out if the device is used by a normal user?
+
+ // Remove the device-to-wallet connection
+ $device->entitlements()->delete();
+
+ // Undelete the device if needed
+ if ($device->trashed()) {
+ $device->restore();
+ }
+ } else {
+ // Create a device
+ $device = self::create(['hash' => $token]);
+ }
// Create a special account
while (true) {
@@ -153,10 +169,15 @@
$device->assignPlan($plan, $wallet = $user->wallets()->first());
// Push entitlements.updated_at to one year in the future
- $device->entitlements()->each(static function ($entitlement) {
- $entitlement->updated_at = \now()->addYearWithoutOverflow();
- $entitlement->save();
- });
+ $threshold = (clone $device->created_at)->addYearWithoutOverflow();
+ if ($threshold > \now()) {
+ $device->entitlements()->each(static function ($entitlement) use ($threshold) {
+ $entitlement->updated_at = $threshold;
+ $entitlement->save();
+ });
+ }
+
+ // FIXME: Should this bump signup_tokens.counter, as it does for user signup?
// TODO: Trigger payment mandate creation?
diff --git a/src/app/Http/Controllers/API/V4/DeviceController.php b/src/app/Http/Controllers/API/V4/DeviceController.php
--- a/src/app/Http/Controllers/API/V4/DeviceController.php
+++ b/src/app/Http/Controllers/API/V4/DeviceController.php
@@ -142,11 +142,6 @@
// TODO: Validate that the plan is device-only, don't accept a user plan here
- // Check if a device already exists
- if (Device::withTrashed()->where('hash', $token)->exists()) {
- return $this->errorResponse(500);
- }
-
// TODO: Should we get the password from the device? Then we'd not have to return it back at the end
$password = Utils::generatePassphrase();
diff --git a/src/tests/Feature/Controller/DeviceTest.php b/src/tests/Feature/Controller/DeviceTest.php
--- a/src/tests/Feature/Controller/DeviceTest.php
+++ b/src/tests/Feature/Controller/DeviceTest.php
@@ -196,8 +196,39 @@
$this->assertNotEmpty($json['access_token']);
$device = Device::where('hash', $this->hash)->first();
+ $account = $device->account;
$this->assertTrue(!empty($device));
+ $this->assertSame($account->email, $json['user']['email']);
+ $this->assertSame(User::ROLE_DEVICE, $account->role);
+ $this->assertSame($plan->id, $account->getSetting('plan_id'));
+ $this->assertSame($this->hash, $account->getSetting('signup_token'));
+
+ $entitlements = $device->wallet()->entitlements()->get();
+ $this->assertCount(1, $entitlements);
+ $this->assertSame($sku->id, $entitlements[0]->sku_id);
+ $this->assertStringContainsString('2026-02-02', $entitlements[0]->updated_at->toDateString());
+
+ $device->created_at = \now()->subMonthsWithoutOverflow();
+ $device->save();
+
+ // Note: without this finding the proper wallet may not work because of how Device::wallet() works
+ Carbon::setTestNow(Carbon::createFromDate(2025, 3, 4));
+
+ // Signup again
+ $response = $this->post("api/v4/device/{$this->hash}/signup", $post);
+ $response->assertStatus(200);
+
+ $json = $response->json();
+
+ $this->assertSame('success', $json['status']);
+ $this->assertSame('bearer', $json['token_type']);
+ $this->assertTrue(!empty($json['expires_in']) && is_int($json['expires_in']) && $json['expires_in'] > 0);
+ $this->assertNotEmpty($json['access_token']);
+
+ $device = Device::where('hash', $this->hash)->first();
+
+ $this->assertTrue($device->account->id != $account->id);
$this->assertSame($device->account->email, $json['user']['email']);
$this->assertSame(User::ROLE_DEVICE, $device->account->role);
$this->assertSame($plan->id, $device->account->getSetting('plan_id'));
@@ -206,7 +237,8 @@
$entitlements = $device->wallet()->entitlements()->get();
$this->assertCount(1, $entitlements);
$this->assertSame($sku->id, $entitlements[0]->sku_id);
- $this->assertStringContainsString('2026-02-02', $entitlements[0]->updated_at->toDateString());
+ $this->assertStringContainsString('2025-03-04', $entitlements[0]->created_at->toDateString());
+ $this->assertStringContainsString('2026-01-02', $entitlements[0]->updated_at->toDateString());
}
private function initTestDevice(): array

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 7:13 PM (2 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18825895
Default Alt Text
D5649.1775243621.diff (5 KB)

Event Timeline