90 lines
5.5 KiB
Transact-SQL
90 lines
5.5 KiB
Transact-SQL
-- iCONAbpFX 的闭环补丁:库从 staging 拷来后执行一次(loop.ps1 reset-abp -Init),之后 BACKUP 到实例默认备份目录留底。
|
||
--
|
||
-- 签名密钥不在库里:ABP 用 AddDeveloperSigningCredential,从宿主目录的 tempkey.jwk 读,
|
||
-- 没有就生成。loop.ps1 deploy 会删掉发布目录里的 tempkey.*,让本机生成一把只在 run\abp 里的新密钥,
|
||
-- 所以闭环签出的 token 在 staging / 生产都验不过。(方案 v4 §2.1 以为密钥入库,实际不是。)
|
||
--
|
||
-- 这里只换三样凭据,让闭环不必知道 staging 的明文:
|
||
-- setsail 的 client secret → loop-setsail-secret
|
||
-- FX_App 的 client secret → loop-fxapp-secret
|
||
-- admin 的密码(iXserver 用 FX_App + password 授权取模板)→ Loop@123456
|
||
-- 明文都在 config\loop.psd1 里,是闭环专用的假值。
|
||
--
|
||
-- 另外改一处模板配置(第 3 节):epro_ig_demo 的条款组补上「Agreement Button (Line IG)」。
|
||
-- 整段可重复执行,结果不变。
|
||
|
||
SET NOCOUNT ON;
|
||
SET XACT_ABORT ON;
|
||
BEGIN TRANSACTION;
|
||
|
||
------------------------------------------------------------------------------------------------
|
||
-- 1. setsail 的 secret:IdentityServer4 存的是 Base64(SHA256(UTF8(secret)))
|
||
------------------------------------------------------------------------------------------------
|
||
DECLARE @setsail UNIQUEIDENTIFIER = (SELECT Id FROM dbo.IdentityServerClients WHERE ClientId = N'setsail');
|
||
IF @setsail IS NULL THROW 50001, N'iCONAbpFX 里没有 setsail client,库是不是从 staging 拷的?', 1;
|
||
|
||
DELETE FROM dbo.IdentityServerClientSecrets WHERE ClientId = @setsail;
|
||
INSERT INTO dbo.IdentityServerClientSecrets (ClientId, Type, Value, Description, Expiration)
|
||
VALUES (@setsail, N'SharedSecret', N'ooFrp78vixE5Hq+OfnE3FXBedZPUiT8mjNzICr2EB80=', N'loop env', NULL);
|
||
|
||
-- FX_App 同理
|
||
DECLARE @fxapp UNIQUEIDENTIFIER = (SELECT Id FROM dbo.IdentityServerClients WHERE ClientId = N'FX_App');
|
||
IF @fxapp IS NULL THROW 50003, N'iCONAbpFX 里没有 FX_App client', 1;
|
||
|
||
DELETE FROM dbo.IdentityServerClientSecrets WHERE ClientId = @fxapp;
|
||
INSERT INTO dbo.IdentityServerClientSecrets (ClientId, Type, Value, Description, Expiration)
|
||
VALUES (@fxapp, N'SharedSecret', N'4wsAVCVjGIuA3sm8w1VV1yvrlD9+nrONjlWXabX6cJw=', N'loop env', NULL);
|
||
|
||
------------------------------------------------------------------------------------------------
|
||
-- 2. admin 的密码:ASP.NET Core Identity V3 格式(HMACSHA256,10000 次,16 字节盐)
|
||
-- 盐是固定的 'loop-env-salt-01',补丁可重复执行、结果不变
|
||
------------------------------------------------------------------------------------------------
|
||
IF NOT EXISTS (SELECT 1 FROM dbo.AbpUsers WHERE UserName = N'admin' AND TenantId IS NULL)
|
||
THROW 50002, N'iCONAbpFX 里没有 host 的 admin 用户', 1;
|
||
|
||
UPDATE dbo.AbpUsers
|
||
SET PasswordHash = N'AQAAAAEAACcQAAAAEGxvb3AtZW52LXNhbHQtMDHzcKLvk4EOtgWerM+7p4SzG/uo/xPnsQw7mAP1Jo6Gvw==',
|
||
SecurityStamp = CONVERT(NVARCHAR(36), NEWID()),
|
||
AccessFailedCount = 0,
|
||
LockoutEnd = NULL
|
||
WHERE UserName = N'admin' AND TenantId IS NULL;
|
||
|
||
------------------------------------------------------------------------------------------------
|
||
-- 3. epro_ig_demo 的条款组补上 Agree 按钮
|
||
-- Line 从问候模板按位置切条款:[Agreement (Line IG), Agreement Button (Line IG), Agreed, Select Language, …];
|
||
-- IG 走条款专用分组,从 staging 拷来时 AgreementMessageTemplateIdsJson 只有 Agreement (Line IG),
|
||
-- 缺了第二条「Please click Agree」,用户收到条款没有按钮可点。这里照 Line 的顺序追加到第二位。
|
||
-- staging 本身没改,闭环在这一处与 staging 不同
|
||
------------------------------------------------------------------------------------------------
|
||
DECLARE @agreeButton NVARCHAR(36) = (SELECT LOWER(CONVERT(NVARCHAR(36), Id)) FROM dbo.iCON_MT_MessageTemplates
|
||
WHERE Name = N'Agreement Button (Line IG)' AND IsDeleted = 0);
|
||
IF @agreeButton IS NULL THROW 50004, N'iCONAbpFX 里没有模板 Agreement Button (Line IG)', 1;
|
||
|
||
DECLARE @igReply UNIQUEIDENTIFIER = (SELECT s.Id FROM dbo.iCON_Chat_AutoReplySettings s
|
||
JOIN dbo.iCON_Chat_ChatServiceAccounts a ON a.Id = s.ChatServiceAccountId
|
||
WHERE a.Code = N'epro_ig_demo' AND a.IsDeleted = 0 AND s.IsDeleted = 0 AND s.Name = N'Default');
|
||
IF @igReply IS NULL THROW 50005, N'iCONAbpFX 里没有 epro_ig_demo 的 Default 自动回复设置', 1;
|
||
|
||
UPDATE dbo.iCON_Chat_AutoReplySettings
|
||
SET AgreementMessageTemplateIdsJson = JSON_MODIFY(AgreementMessageTemplateIdsJson, 'append $', @agreeButton),
|
||
ConcurrencyStamp = REPLACE(CONVERT(NVARCHAR(36), NEWID()), '-', ''),
|
||
LastModificationTime = GETDATE()
|
||
WHERE Id = @igReply
|
||
AND ISJSON(AgreementMessageTemplateIdsJson) = 1
|
||
AND NOT EXISTS (SELECT 1 FROM OPENJSON(AgreementMessageTemplateIdsJson) WHERE LOWER(value) = @agreeButton);
|
||
|
||
COMMIT TRANSACTION;
|
||
|
||
SELECT c.ClientId, c.Enabled, c.AccessTokenLifetime,
|
||
(SELECT COUNT(*) FROM dbo.IdentityServerClientSecrets s WHERE s.ClientId = c.Id) AS secrets
|
||
FROM dbo.IdentityServerClients c
|
||
WHERE c.ClientId IN (N'setsail', N'FX_App');
|
||
|
||
SELECT a.Code, t.[key] AS position, m.Name AS agreement_template
|
||
FROM dbo.iCON_Chat_AutoReplySettings s
|
||
JOIN dbo.iCON_Chat_ChatServiceAccounts a ON a.Id = s.ChatServiceAccountId
|
||
CROSS APPLY OPENJSON(s.AgreementMessageTemplateIdsJson) t
|
||
LEFT JOIN dbo.iCON_MT_MessageTemplates m ON LOWER(CONVERT(NVARCHAR(36), m.Id)) = LOWER(t.value)
|
||
WHERE s.Id = @igReply
|
||
ORDER BY CONVERT(INT, t.[key]);
|