mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-04 16:23:22 +00:00
ADD - persist lock screen notifications
This commit is contained in:
@@ -19,6 +19,11 @@ Config.Phone = {
|
||||
DeviceName = "iFruit Phone",
|
||||
}
|
||||
|
||||
Config.NotificationTest = {
|
||||
Command = "phonenotifytest",
|
||||
AdminGroups = { "admin" },
|
||||
}
|
||||
|
||||
Config.Security = {
|
||||
PasscodePepperConvar = "sky_phone_passcode_pepper",
|
||||
MaximumAttempts = 5,
|
||||
|
||||
@@ -42,7 +42,7 @@ Locales["en"] = {
|
||||
open = "Open Control Center", play = "Play", previous = "Previous track", quickActions = "Quick actions",
|
||||
timer = "Timer", unmuteRingtone = "Unmute ringtone and notifications", volume = "Volume", wifi = "Wi-Fi",
|
||||
},
|
||||
Notifications = { now = "now" },
|
||||
Notifications = { clearAll = "Clear All", now = "now" },
|
||||
LockScreen = {
|
||||
label = "Lock Screen", flashlight = "Flashlight", camera = "Camera", swipeUp = "Swipe up to open",
|
||||
passcode = {
|
||||
|
||||
@@ -53,6 +53,7 @@ server_scripts {
|
||||
'source/bridge/server/inventory/*.lua',
|
||||
'source/server/db_migrate.lua',
|
||||
'source/server/phone.lua',
|
||||
'source/server/debug.lua',
|
||||
'source/server/sim.lua',
|
||||
'source/server/calls.lua',
|
||||
'source/server/media.lua',
|
||||
|
||||
@@ -13,6 +13,7 @@ local server_callbacks = {
|
||||
"security:change-passcode",
|
||||
"security:disable-passcode",
|
||||
"device:save",
|
||||
"notifications:save",
|
||||
"device:factory-reset",
|
||||
"account:login",
|
||||
"account:register",
|
||||
@@ -616,6 +617,10 @@ RegisterNetEvent("sky_phone:billing:new", function(data)
|
||||
SendNUIMessage({ type = "billing:new", data = data })
|
||||
end)
|
||||
|
||||
RegisterNetEvent("sky_phone:notification:test", function(data)
|
||||
SendNUIMessage({ type = "notification:show", data = data })
|
||||
end)
|
||||
|
||||
RegisterNetEvent("sky_phone:messages:changed", function(data)
|
||||
SendNUIMessage({ type = "messages:changed", data = data })
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
Bridge.Database.AfterMigration("sky_phone", function()
|
||||
RegisterCommand(Config.NotificationTest.Command, function(source)
|
||||
if source == 0 then
|
||||
print(("[sky_phone] /%s must be used by an in-game admin."):format(Config.NotificationTest.Command))
|
||||
return
|
||||
end
|
||||
|
||||
if not Bridge.Framework.HasAdminGroup(source, Config.NotificationTest.AdminGroups) then
|
||||
Bridge.Debug(
|
||||
"warn",
|
||||
"[sky_phone] Source %s attempted to use the notification test command without an admin group.",
|
||||
tostring(source)
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
local slots = Bridge.Inventory.GetSlotsWithItem(source, Config.Phone.Item)
|
||||
local slot = slots[1]
|
||||
if not slot then
|
||||
Bridge.Debug(
|
||||
"warn",
|
||||
"[sky_phone] Notification test failed because source %s has no phone item.",
|
||||
tostring(source)
|
||||
)
|
||||
TriggerClientEvent("sky_phone:device:error", source, "phone_slot_missing")
|
||||
return
|
||||
end
|
||||
|
||||
local imei, device_error = SkyPhone.EnsureDevice(source, slot)
|
||||
if not imei then
|
||||
Bridge.Debug(
|
||||
"warn",
|
||||
"[sky_phone] Notification test could not resolve a device for source %s: %s.",
|
||||
tostring(source),
|
||||
tostring(device_error)
|
||||
)
|
||||
TriggerClientEvent("sky_phone:device:error", source, device_error or "request_failed")
|
||||
return
|
||||
end
|
||||
|
||||
local device = SkyPhone.LoadDevice(imei)
|
||||
if not device then
|
||||
Bridge.Debug(
|
||||
"error",
|
||||
"[sky_phone] Notification test could not load device %s for source %s.",
|
||||
imei,
|
||||
tostring(source)
|
||||
)
|
||||
TriggerClientEvent("sky_phone:device:error", source, "request_failed")
|
||||
return
|
||||
end
|
||||
|
||||
local settings = Bridge.Database.Query([[
|
||||
SELECT `payload`
|
||||
FROM `sky_phone_device_data`
|
||||
WHERE `device_imei` = ? AND `namespace` = 'settings'
|
||||
LIMIT 1
|
||||
]], { imei })[1]
|
||||
|
||||
TriggerClientEvent("sky_phone:notification:test", source, {
|
||||
appId = "messages",
|
||||
title = "Notification Test",
|
||||
text = "This is a test notification.",
|
||||
device = {
|
||||
imei = imei,
|
||||
name = device.device_name,
|
||||
settings = settings and settings.payload or nil,
|
||||
},
|
||||
})
|
||||
|
||||
Bridge.Debug(
|
||||
"info",
|
||||
"[sky_phone] Sent a test notification to source %s on device %s.",
|
||||
tostring(source),
|
||||
imei
|
||||
)
|
||||
end, false)
|
||||
end)
|
||||
@@ -947,6 +947,60 @@ Bridge.Callbacks.Register("sky_phone:device:save", function(source, data)
|
||||
return { success = true, data = { revision = 1 } }
|
||||
end)
|
||||
|
||||
Bridge.Callbacks.Register("sky_phone:notifications:save", function(source, data)
|
||||
if not SkyPhone.AllowOperation(source, "notifications_save", 240, 60) then
|
||||
return { success = false, error = "rate_limited" }
|
||||
end
|
||||
if type(data) ~= "table" or not SkyPhoneImei.IsValid(data.imei) or type(data.payload) ~= "table" then
|
||||
return { success = false, error = "invalid_request" }
|
||||
end
|
||||
if #SkyPhone.FindDeviceSlots(source, data.imei) == 0 then
|
||||
Bridge.Debug(
|
||||
"warn",
|
||||
"[sky_phone] Source %s attempted to save notifications for unowned device %s.",
|
||||
tostring(source),
|
||||
tostring(data.imei)
|
||||
)
|
||||
return { success = false, error = "device_not_owned" }
|
||||
end
|
||||
if data.payload.version ~= 1 or type(data.payload.items) ~= "table" then
|
||||
return { success = false, error = "invalid_request" }
|
||||
end
|
||||
local item_count = #data.payload.items
|
||||
local key_count = 0
|
||||
for key in pairs(data.payload.items) do
|
||||
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > item_count then
|
||||
return { success = false, error = "invalid_request" }
|
||||
end
|
||||
key_count = key_count + 1
|
||||
end
|
||||
if key_count ~= item_count then
|
||||
return { success = false, error = "invalid_request" }
|
||||
end
|
||||
for _, item in ipairs(data.payload.items) do
|
||||
if type(item) ~= "table"
|
||||
or type(item.appId) ~= "string" or #item.appId > 64
|
||||
or type(item.id) ~= "string" or #item.id > 100
|
||||
or type(item.title) ~= "string" or #item.title > 200
|
||||
or type(item.text) ~= "string" or #item.text > 2000
|
||||
or (item.subtitle ~= nil and (type(item.subtitle) ~= "string" or #item.subtitle > 200))
|
||||
then
|
||||
return { success = false, error = "invalid_request" }
|
||||
end
|
||||
end
|
||||
|
||||
local encoded = json.encode(data.payload)
|
||||
if #encoded > max_device_data_bytes then
|
||||
return { success = false, error = "payload_too_large" }
|
||||
end
|
||||
Bridge.Database.Query([[
|
||||
INSERT INTO `sky_phone_device_data` (`device_imei`, `namespace`, `payload`)
|
||||
VALUES (?, 'notifications', ?)
|
||||
ON DUPLICATE KEY UPDATE `payload` = VALUES(`payload`), `revision` = `revision` + 1
|
||||
]], { data.imei, encoded })
|
||||
return { success = true }
|
||||
end)
|
||||
|
||||
for _, endpoint in ipairs({ "account:login", "mail:login" }) do
|
||||
Bridge.Callbacks.Register("sky_phone:" .. endpoint, function(source, data)
|
||||
return authenticate(source, data, false)
|
||||
|
||||
Reference in New Issue
Block a user