diff --git a/Inotify.Vue/package.json b/Inotify.Vue/package.json index b54f4bd..fd22803 100644 --- a/Inotify.Vue/package.json +++ b/Inotify.Vue/package.json @@ -24,6 +24,7 @@ "normalize.css": "7.0.0", "nprogress": "0.2.0", "path-to-regexp": "2.4.0", + "qrcodejs": "^1.0.0", "vue": "2.6.10", "vue-router": "3.0.6", "vuex": "3.1.0" diff --git a/Inotify.Vue/src/views/manager/settingpro/sendauths/index.vue b/Inotify.Vue/src/views/manager/settingpro/sendauths/index.vue index d47e164..1feb746 100644 --- a/Inotify.Vue/src/views/manager/settingpro/sendauths/index.vue +++ b/Inotify.Vue/src/views/manager/settingpro/sendauths/index.vue @@ -12,7 +12,7 @@ - + @@ -71,6 +71,7 @@ import { getSendTemplates, addAuthInfo, deepClone, + getSendKey } from '@/api/setting' @@ -102,7 +103,7 @@ export default { isModify: false, authform: {}, title: "设置", - + sendKey: "" } }, created() { @@ -117,14 +118,23 @@ export default { }) getSendTemplates().then((response) => { if (response.code == 200) { - this.sendTemplates = response.data; } }) + getSendKey().then(response => { + if (response.code == 200) { + this.sendKey = response.data; + } + }) }, selectTemplateChange(selectTemplate) { - - this.selectTemplate = deepClone(selectTemplate); + this.selectTemplate = deepClone(selectTemplate) + if (this.selectTemplate.warning) { + this.$message({ + message: this.selectTemplate.warning, + type: 'warning' + }) + } }, submitForm(formName) { this.$refs[formName].validate((valid) => { @@ -181,8 +191,23 @@ export default { this.title = '修改设置' this.isModify = true; this.selectTemplate = deepClone(row); - this.dialogVisible = true; + if (this.selectTemplate.type == "Bark") { + let wPath = window.document.location.href; + let pathName = this.$route.path; + let pos = wPath.indexOf(pathName); + let localhostPath = wPath.substring(0, pos); + localhostPath = localhostPath.replace("#", ""); + var devieItem = this.selectTemplate.values.find(item => { + return item.name == "DeviceKey" + }) + var sendUrlItem = this.selectTemplate.values.find(item => { + return item.name == "SendUrl" + }); + sendUrlItem.value = localhostPath + "?act=" + this.sendKey + "/" + devieItem.value + "/{title}/{data}" + } + + this.dialogVisible = true; }, deleteAuth(index, row) { deleteAuthInfo(row.sendAuthId).then((response) => { @@ -213,24 +238,25 @@ export default { } } - diff --git a/Inotify.Vue/src/views/manager/settingpro/sendkey/index.vue b/Inotify.Vue/src/views/manager/settingpro/sendkey/index.vue index 2f54288..dbacf85 100644 --- a/Inotify.Vue/src/views/manager/settingpro/sendkey/index.vue +++ b/Inotify.Vue/src/views/manager/settingpro/sendkey/index.vue @@ -26,13 +26,23 @@ - + 重置SendKey + + BARK授权 + + + + + +
+
+
@@ -95,10 +105,15 @@ export default { let pos = wPath.indexOf(pathName); let localhostPath = wPath.substring(0, pos); localhostPath = localhostPath.replace("#", ""); - this.keyForm.sendUrlTitle = localhostPath + 'api/'+ this.keyForm.sendKey+'.send' + "/{title}" - this.keyForm.sendUrl = localhostPath + 'api/'+ this.keyForm.sendKey+'.send' + "/{title}/{data}" - // this.keyForm.sendUrl = localhostPath + 'api/send?token=' + this.keyForm.sendKey + "&title={title}&data={data}" + this.keyForm.sendUrlTitle = localhostPath + this.keyForm.sendKey + '.send' + "/{title}" + this.keyForm.sendUrl = localhostPath + this.keyForm.sendKey + '.send' + "/{title}/{data}" + this.keyForm.barkUrl = wPath.substring(0, pos - 2) + '?act=' + this.keyForm.sendKey this.listLoading = false; + new QRCode(document.getElementById("qrcode"), { + text: this.keyForm.barkUrl, + width: 150, + height: 150, + }); }); }, onMessage(fromname) { diff --git a/Inotify.Vue/src/views/manager/settingsys/systemglobal/index.vue b/Inotify.Vue/src/views/manager/settingsys/systemglobal/index.vue index b9d301e..d50bed3 100644 --- a/Inotify.Vue/src/views/manager/settingsys/systemglobal/index.vue +++ b/Inotify.Vue/src/views/manager/settingsys/systemglobal/index.vue @@ -36,6 +36,17 @@
+ + BARK授权 + + > + + + + + + + 确认修改 diff --git a/Inotify.Vue/vue.config.js b/Inotify.Vue/vue.config.js index 87fb662..20bef89 100644 --- a/Inotify.Vue/vue.config.js +++ b/Inotify.Vue/vue.config.js @@ -7,7 +7,7 @@ function resolve(dir) { } const name = defaultSettings.title || 'Inotify' -const port = process.env.port || process.env.npm_config_port || 9528 +const port = process.env.port || process.env.npm_config_port || 9000 const axiosV = require('axios/package.json').version const echartsV = require('echarts/package.json').version @@ -43,7 +43,8 @@ const cdn = { `https://cdn.bootcdn.net/ajax/libs/vue-router/${routerV}/vue-router.min.js`, `https://cdn.bootcdn.net/ajax/libs/element-ui/${elementV}/locale/zh-CN.js`, `https://cdn.bootcdn.net/ajax/libs/js-cookie/${cookieV}/js.cookie.min.js`, - `https://cdn.bootcdn.net/ajax/libs/nprogress/${nprogressV}/nprogress.min.js` + `https://cdn.bootcdn.net/ajax/libs/nprogress/${nprogressV}/nprogress.min.js`, + `https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.js` ] } diff --git a/Inotify/.editorconfig b/Inotify/.editorconfig index af9eccc..107674a 100644 --- a/Inotify/.editorconfig +++ b/Inotify/.editorconfig @@ -17,3 +17,9 @@ dotnet_diagnostic.CS8602.severity = none # CS8600: 将 null 文本或可能的 null 值转换为不可为 null 类型。 dotnet_diagnostic.CS8600.severity = none + +# IDE0037: 使用推断的成员名称 +dotnet_diagnostic.IDE0037.severity = none + +# IDE0008: 使用显式类型 +dotnet_diagnostic.IDE0008.severity = none diff --git a/Inotify/Common/Extensions.cs b/Inotify/Common/Extensions.cs index 38273a6..5c9d4d4 100644 --- a/Inotify/Common/Extensions.cs +++ b/Inotify/Common/Extensions.cs @@ -9,6 +9,8 @@ namespace Inotify.Common { public static class Extensions { + static int rep = 0; + /// /// MD5加密字符串(32位大写) /// @@ -30,6 +32,7 @@ namespace Inotify.Common public static string Base64Encode(this string source) { + if (string.IsNullOrEmpty(source)) return ""; byte[] bytes = (Encoding.UTF8.GetBytes(source)); return Convert.ToBase64String(bytes); @@ -37,8 +40,32 @@ namespace Inotify.Common public static string Base64Decode(this string source) { + if (string.IsNullOrEmpty(source)) return ""; var bytes = Convert.FromBase64String(source); return System.Text.Encoding.Default.GetString(bytes); } + + public static string GenerateCheckCode(this int codeCount) + { + string str = string.Empty; + long num2 = DateTime.Now.Ticks + rep; + rep++; + Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> rep))); + for (int i = 0; i < codeCount; i++) + { + char ch; + int num = random.Next(); + if ((num % 2) == 0) + { + ch = (char)(0x30 + ((ushort)(num % 10))); + } + else + { + ch = (char)(0x41 + ((ushort)(num % 0x1a))); + } + str += ch.ToString(); + } + return str; + } } } diff --git a/Inotify/Controllers/BarkControlor.cs b/Inotify/Controllers/BarkControlor.cs index 7e710f6..b9df48b 100644 --- a/Inotify/Controllers/BarkControlor.cs +++ b/Inotify/Controllers/BarkControlor.cs @@ -1,4 +1,5 @@ -using Inotify.Data; +using Inotify.Common; +using Inotify.Data; using Inotify.Data.Models; using Inotify.Sends; using Inotify.Sends.Products; @@ -13,106 +14,115 @@ using System.Threading.Tasks; namespace Inotify.Controllers { - public class DeviceInfo - { - public string? Token { get; set; } - - public string? Key { get; set; } - - public string? DeviceToken { get; set; } - - public string? Device_key { get; set; } - - public string? Device_token { get; set; } - } - [ApiController] [Route("/")] public class BarkControlor : BaseControlor { [HttpGet, Route("Ping")] - public JsonResult Ping(string? token) + public JsonResult Ping() { - return OK(); + return Me("pong"); } [HttpGet, Route("Info")] - public JsonResult Info(string? token) + public JsonResult Info() { + var dateTime = System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location); + var devices = DBManager.Instance.DBase.Query().Count(); return Json(new { - version = "v2", - build = "2021.03.29", + version = "v2.0.1", + build = dateTime.ToString("yyyy-MM-dd HH:mm:ss"), arch = RuntimeInformation.OSDescription, - commit = "inotfy", - devices = RuntimeInformation.OSDescription + commit = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(), + devices }); - } [HttpGet, Route("Healthz")] - public string Healthz(string? token) + public string Healthz() { return "ok"; } + [HttpGet, Route("Register")] + public JsonResult Register(string? act, string? key, string? devicetoken, string? device_key) => !string.IsNullOrEmpty(device_key) ? + Register(device_key) : Register(act, key, devicetoken); + [HttpPost, Route("Register")] - public JsonResult Register(DeviceInfo deviceInfo) + public JsonResult Register(string? act, string? device_key, string? device_token) { - if (!string.IsNullOrEmpty(deviceInfo.Key)) - deviceInfo.Device_key = deviceInfo.Key; + if (string.IsNullOrEmpty(act)) + return Fail(400, "request bind failed : act is empty"); - if (!string.IsNullOrEmpty(deviceInfo.DeviceToken)) - deviceInfo.Device_token = deviceInfo.DeviceToken; + if (string.IsNullOrEmpty(device_token)) + return Fail(400, "request bind failed : device_token is empty"); - if (string.IsNullOrEmpty(deviceInfo.Device_key)) - return Fail(400, "request bind failed : device_key is empty"); - - if (string.IsNullOrEmpty(deviceInfo.Device_token)) - return Fail(400, "request bind failed : device_token not empty"); - - var userInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.Token == deviceInfo.Token); + var userInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.Token == act); if (userInfo == null) { - return Fail(400, "request bind failed : device not registered"); + return Fail(400, "request bind failed : act is not registered"); } else { - - var barkAuth = new BarkAuth() { DeviceToken = deviceInfo.Device_token }; + BarkAuth barkAuth = null; + SendAuthInfo barkSendAuthInfo = null; var barkTemplateAttribute = typeof(BarkSendTemplate).GetCustomAttributes(typeof(SendMethodKeyAttribute), false).OfType().First(); - var barkSendAuthInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.UserId == userInfo.Id && e.SendMethodTemplate == barkTemplateAttribute.Key); + + if (!string.IsNullOrEmpty(device_key)) + { + barkSendAuthInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.Key == device_key); + if (barkSendAuthInfo != null) + { + barkAuth = JsonConvert.DeserializeObject(barkSendAuthInfo.AuthData); + barkAuth.DeviceToken = device_token; + barkSendAuthInfo.AuthData = JsonConvert.SerializeObject(barkAuth); + barkSendAuthInfo.ModifyTime = DateTime.Now; + DBManager.Instance.DBase.Update(barkSendAuthInfo); + } + } + if (barkSendAuthInfo == null) { + device_key = 16.GenerateCheckCode(); + barkAuth = new BarkAuth() { DeviceKey = device_key, DeviceToken = device_token, IsArchive = "1", AutoMaticallyCopy = "1", Sound = "1107" }; barkSendAuthInfo = new SendAuthInfo() { Name = barkTemplateAttribute.Name, SendMethodTemplate = barkTemplateAttribute.Key, + Key = device_key, AuthData = JsonConvert.SerializeObject(barkAuth), UserId = userInfo.Id, CreateTime = DateTime.Now, - ModifyTime = DateTime.Now + ModifyTime = DateTime.Now, + Active = true, }; - - var sendAuthId = Convert.ToInt32(DBManager.Instance.DBase.Insert(barkSendAuthInfo)); - userInfo.SendAuthId = sendAuthId; - DBManager.Instance.DBase.Update(userInfo, e => e.SendAuthId); - } - else - { - barkSendAuthInfo.AuthData = JsonConvert.SerializeObject(barkAuth); - barkSendAuthInfo.ModifyTime = DateTime.Now; - DBManager.Instance.DBase.Update(barkSendAuthInfo); + DBManager.Instance.DBase.Insert(barkSendAuthInfo); } return Json(new { - key = deviceInfo.Device_key, - device_key = deviceInfo.Device_key, - device_token = deviceInfo.Device_token + key = device_key, + device_key = device_key, + device_token = device_token }); } } + + [HttpGet, Route("RegisterCheck")] + public JsonResult Register(string device_key) + { + if (string.IsNullOrEmpty(device_key)) + { + return Fail(400, "device key is empty"); + } + if (!DBManager.Instance.DBase.Query().Any(e => e.Key == device_key)) + { + return Fail(400, "device not registered"); + } + + return OK(); + } } } diff --git a/Inotify/Controllers/BaseControlor.cs b/Inotify/Controllers/BaseControlor.cs index ae99519..7463749 100644 --- a/Inotify/Controllers/BaseControlor.cs +++ b/Inotify/Controllers/BaseControlor.cs @@ -70,7 +70,7 @@ namespace Inotify.Controllers { code = 200, message = "sucess", - timestamp = (DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds }); } @@ -81,7 +81,17 @@ namespace Inotify.Controllers code = 200, message = "sucess", data = obj ?? "", - timestamp = (DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + }); + } + + protected JsonResult Me(string message) + { + return Json(new + { + code = 200, + message = message, + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds }); } @@ -91,7 +101,7 @@ namespace Inotify.Controllers { code = 404, message = "failed", - timestamp = (DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds }); } @@ -99,9 +109,9 @@ namespace Inotify.Controllers { return Json(new { - code, + code= code, message = "failed", - timestamp = (DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds }); } @@ -109,9 +119,9 @@ namespace Inotify.Controllers { return new JsonResult(new { - code, - message, - timestamp = (DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + code=code, + message=message, + timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds }); } diff --git a/Inotify/Controllers/SendControlor.cs b/Inotify/Controllers/SendControlor.cs index 96c47fa..5464ccc 100644 --- a/Inotify/Controllers/SendControlor.cs +++ b/Inotify/Controllers/SendControlor.cs @@ -12,20 +12,39 @@ namespace Inotify.Controllers public class SendController : BaseControlor { [HttpGet, Route("send")] - public JsonResult Send(string token, string title, string? data) + public JsonResult Send(string token, string title, string? data, string? key) { - if (DBManager.Instance.IsSendKey(token)) + if (DBManager.Instance.IsToken(token, out bool hasActive)) { + if (!hasActive) return Fail(400, "you have no tunnel is acitve"); + + if (!string.IsNullOrEmpty(key)) + { + if (DBManager.Instance.IsSendKey(key, out bool isActive)) + { + if (!isActive) + { + return Fail(400, $"device:{key} tunnel is not acitve"); + } + } + else + { + return Fail(400, $"device:{key} is not registered"); + } + } + var message = new SendMessage() { Token = token, Title = title, Data = data, + Key = key, }; - if (SendTaskManager.Instance.SendMessage(message)) - return OK(); + + if (SendTaskManager.Instance.SendMessage(message)) return OK(); } - return Fail(); + + return Fail(400, $"token:{token} is not registered"); } } } diff --git a/Inotify/Controllers/SettingControlor.cs b/Inotify/Controllers/SettingControlor.cs index 54a5337..2cd1f18 100644 --- a/Inotify/Controllers/SettingControlor.cs +++ b/Inotify/Controllers/SettingControlor.cs @@ -39,6 +39,7 @@ namespace Inotify.Controllers var userInfo = DBManager.Instance.GetUser(UserName); if (userInfo != null) { + var barkTemplateAttribute = typeof(BarkSendTemplate).GetCustomAttributes(typeof(SendMethodKeyAttribute), false).OfType().First(); var sendAuthInfos = DBManager.Instance.DBase.Query().Where(e => e.UserId == userInfo.Id).ToArray(); var userSendTemplates = new List(); foreach (var sendAuthInfo in sendAuthInfos) @@ -53,6 +54,10 @@ namespace Inotify.Controllers sendTemplate.AuthToTemplate(sendAuthInfo.AuthData); userSendTemplates.Add(sendTemplate); } + if (barkTemplateAttribute.Key == sendTemplate.Key) + { + sendTemplate.Values.FirstOrDefault(e => e.Name == nameof(BarkSendTemplate.Auth.SendUrl)).Value = ""; + } } return OK(userSendTemplates); @@ -100,10 +105,9 @@ namespace Inotify.Controllers if (userInfo != null && inputTemeplate.Key != null && inputTemeplate.Name != null) { var barkKey = typeof(BarkSendTemplate).GetCustomAttributes(typeof(SendMethodKeyAttribute), false).OfType().First().Key; - if (barkKey == inputTemeplate.Key - && DBManager.Instance.DBase.Query().FirstOrDefault(e => e.UserId == userInfo.Id && e.SendMethodTemplate == barkKey) != null) + if (barkKey == inputTemeplate.Key) { - return Fail(406, "您只能添加一个BARK通道"); + return Fail(406, "BARK通道勿手动添加,请使用APP添加BARK地址绑定"); } else { @@ -131,6 +135,7 @@ namespace Inotify.Controllers var userInfo = DBManager.Instance.GetUser(UserName); if (userInfo != null) { + var barkTemplateAttribute = typeof(BarkSendTemplate).GetCustomAttributes(typeof(SendMethodKeyAttribute), false).OfType().First(); var oldSendInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.Id == inputTemeplate.SendAuthId); if (oldSendInfo != null && inputTemeplate.Name != null) { diff --git a/Inotify/Controllers/SetttingSysControlor.cs b/Inotify/Controllers/SetttingSysControlor.cs index 1490aef..9a6d861 100644 --- a/Inotify/Controllers/SetttingSysControlor.cs +++ b/Inotify/Controllers/SetttingSysControlor.cs @@ -30,6 +30,9 @@ namespace Inotify.Controllers githubClientID = SendCacheStore.GetSystemValue("githubClientID"), githubClientSecret = SendCacheStore.GetSystemValue("githubClientSecret"), githubEnable = githubEnable != "" && bool.Parse(githubEnable), + barkKeyId= SendCacheStore.GetSystemValue("barkKeyId"), + barkTeamId = SendCacheStore.GetSystemValue("barkTeamId"), + barkPrivateKey = SendCacheStore.GetSystemValue("barkPrivateKey"), }); } @@ -41,7 +44,10 @@ namespace Inotify.Controllers string? proxyenable, string? githubClientID, string? githubClientSecret, - string? githubEnable) + string? githubEnable, + string? barkKeyId, + string? barkTeamId, + string? barkPrivateKey) { SendCacheStore.SetSystemValue("sendthread", sendthread); SendCacheStore.SetSystemValue("administrators", administrators); @@ -50,6 +56,9 @@ namespace Inotify.Controllers SendCacheStore.SetSystemValue("githubClientID", githubClientID); SendCacheStore.SetSystemValue("githubClientSecret", githubClientSecret); SendCacheStore.SetSystemValue("githubEnable", githubEnable); + SendCacheStore.SetSystemValue("barkKeyId", barkKeyId); + SendCacheStore.SetSystemValue("barkTeamId", barkTeamId); + SendCacheStore.SetSystemValue("barkPrivateKey", barkPrivateKey); SendTaskManager.Instance.Stop(); SendTaskManager.Instance.Run(); diff --git a/Inotify/Data/DBManager.cs b/Inotify/Data/DBManager.cs index b24be20..11a83dc 100644 --- a/Inotify/Data/DBManager.cs +++ b/Inotify/Data/DBManager.cs @@ -105,16 +105,38 @@ namespace Inotify.Data m_dbConnection = new SqliteConnection(string.Format("Data Source={0}", m_dbPath)); + if (m_dbConnection.State == ConnectionState.Closed) m_dbConnection.Open(); - DBase = new NPoco.Database(m_dbConnection, DatabaseType.SQLite); + DBase = new Database(m_dbConnection, DatabaseType.SQLite); + DBase.KeepConnectionAlive = true; m_migrator = new Migrator(DBase); } - public bool IsSendKey(string token) + public bool IsToken(string token,out bool hasActive) { - return DBase.Query().Any(e => e.Token == token); + hasActive = false; + var userInfo= DBase.Query().FirstOrDefault(e => e.Token == token); + if (userInfo != null) + { + hasActive= DBase.Query().Any(e => e.UserId== userInfo.Id && e.Active); + return true; + } + + return false; + } + + public bool IsSendKey(string key, out bool isActive) + { + isActive = false; + var sendAuthInfo = DBase.Query().FirstOrDefault(e => e.Key == key); + if (sendAuthInfo != null) + { + isActive = sendAuthInfo.Active; + return true; + } + return false; } public bool IsUser(string userName) @@ -124,10 +146,10 @@ namespace Inotify.Data public SendUserInfo GetUser(string userName) { - return DBase.Query().First(e => e.UserName == userName); + return DBase.Query().FirstOrDefault(e => e.UserName == userName); } - public string GetAuth(string token, out string guid) + public string GetSendAuthInfo(string token, out string guid) { guid = string.Empty; var upToekn = token.ToUpper(); @@ -142,18 +164,25 @@ namespace Inotify.Data return authInfo.AuthData; } - public void GetAuth(string token, out SendAuthInfo[] sendAuthInfos) + public void GetSendAuthInfos(string token, string key, out SendAuthInfo[] sendAuthInfos) { sendAuthInfos = null; var upToekn = token.ToUpper(); var userInfo = DBManager.Instance.DBase.Query().FirstOrDefault(e => e.Token == upToekn && e.Active); if (userInfo != null) - - sendAuthInfos = DBManager.Instance.DBase.Query().Where(e => e.UserId == userInfo.Id && e.Active).ToArray(); + { + if (string.IsNullOrEmpty(key)) + { + sendAuthInfos = DBManager.Instance.DBase.Query().Where(e => e.UserId == userInfo.Id && e.Active).ToArray(); + } + else + { + sendAuthInfos = DBManager.Instance.DBase.Query().Where(e => e.UserId == userInfo.Id && e.Active &&e.Key==key).ToArray(); + } + } } - public void Run() { @@ -175,10 +204,9 @@ namespace Inotify.Data var builder = new MigrationBuilder(MigrationName, DBase); builder.Append(new Version(2, 0, 0, 0), new V2UpdateMigration()); + builder.Append(new Version(2, 0, 0, 1), new V2001UpdateMigration()); builder.Execute(); } } } - - } diff --git a/Inotify/Data/DBMigrations.cs b/Inotify/Data/DBMigrations.cs index 7c8ccb2..a1c4bf1 100644 --- a/Inotify/Data/DBMigrations.cs +++ b/Inotify/Data/DBMigrations.cs @@ -59,8 +59,7 @@ namespace Inotify.Data { protected override void execute() { - //V2版本允许多通道,激活标记放入SendAuthInfo表中,增加Active列 - //更新原有用户的激活通道 + //V2版本允许多通道,激活标记放入SendAuthInfo表中,增加Active列,同时更新原有用户的激活通道 Migrator.AlterTable().AddColumn(e => e.Active).Execute(); Migrator.Database.UpdateMany().OnlyFields(e => e.Active).Execute(new SendAuthInfo() { Active = false }); var activeUsers = Migrator.Database.Query().ToList(); @@ -75,4 +74,38 @@ namespace Inotify.Data }); } } + + public class V2001UpdateMigration : Migration, IMigration + { + protected override void execute() + { + //V2001版本增加SendInfo的key字段 + Migrator.AlterTable().AddColumn(e => e.Key).Execute(); + + //对AuthInfo的AuthDate字段进行加密 + var sendAuthInfos = Migrator.Database.Query().ToList(); + sendAuthInfos.ForEach(sendAuthInfo => + { + sendAuthInfo.AuthData = sendAuthInfo.AuthDataSave; + Migrator.Database.Update(sendAuthInfo); + }); + + //添加bark密钥相关内容 + Migrator.Database.Insert(new SystemInfo() + { + key = "barkKeyId", + Value = "TEg0VDlWNVU0Ug==".Base64Decode(), + }); + Migrator.Database.Insert(new SystemInfo() + { + key = "barkTeamId", + Value = "NVU4TEJSWEczQQ==".Base64Decode(), + }); + Migrator.Database.Insert(new SystemInfo() + { + key = "barkPrivateKey", + Value = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR1RBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJIa3dkd0lCQVFRZzR2dEMzZzVMNUhnS0dKMitUMWVBMHRPaXZSRXZFQVkyZytqdVJYSmtZTDJnQ2dZSUtvWkl6ajBEQVFlaFJBTkNBQVNtT3MzSmtTeW9HRVdac1VHeEZzLzRwdzFySWxTVjJJQzE5TTh1M0c1a3EzNnVwT3d5RldqOUdpM0VqYzlkM3NDNytTSFJxWHJFQUpvdzgvN3RScFYrCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=".Base64Decode() + }); + } + } } diff --git a/Inotify/Data/Models/SendAuthInfo.cs b/Inotify/Data/Models/SendAuthInfo.cs index 14b7287..13dcd0a 100644 --- a/Inotify/Data/Models/SendAuthInfo.cs +++ b/Inotify/Data/Models/SendAuthInfo.cs @@ -1,5 +1,5 @@ using System; - +using Inotify.Common; namespace Inotify.Data.Models { [NPoco.TableName("sendAuthInfo")] @@ -19,7 +19,20 @@ namespace Inotify.Data.Models public string SendMethodTemplate { get; set; } [NPoco.Column("authData")] - public string AuthData { get; set; } + public string AuthDataSave { get; set; } + + [NPoco.Ignore] + public string AuthData + { + get + { + return AuthDataSave.Base64Decode(); + } + set + { + AuthDataSave = value.Base64Encode(); + } + } [NPoco.Column("modifyTime")] public DateTime ModifyTime { get; set; } @@ -29,5 +42,9 @@ namespace Inotify.Data.Models [NPoco.Column("active")] public bool Active { get; set; } + + [NPoco.Column("key")] + public string Key { get; set; } + } } diff --git a/Inotify/Inotify.csproj b/Inotify/Inotify.csproj index 2a5fbb5..77c8727 100644 --- a/Inotify/Inotify.csproj +++ b/Inotify/Inotify.csproj @@ -6,8 +6,8 @@ Linux Inotify.Program enable - 2.0.0.0 - 2.0.0.0 + 2.0.0.1 + 2.0.0.1 @@ -31,7 +31,7 @@ - PreserveNewest + Always diff --git a/Inotify/Sends/Products/BarkSendTemplate.cs b/Inotify/Sends/Products/BarkSendTemplate.cs index 5bef0da..516341b 100644 --- a/Inotify/Sends/Products/BarkSendTemplate.cs +++ b/Inotify/Sends/Products/BarkSendTemplate.cs @@ -1,9 +1,11 @@ using Inotify.Common; using Inotify.Data; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; using System.Net.Http; @@ -16,166 +18,78 @@ using System.Threading.Tasks; namespace Inotify.Sends.Products { - public class BarkMessage - { - public BarkMessage(string body) : this(string.Empty, body) { } - public BarkMessage(string title, string body) - { - this.Title = title; - this.Body = body; - } - - #region 公共属性 - /// - /// 标题,加粗 - /// - public string Title { get; set; } = string.Empty; - /// - /// 正文 - /// - public string Body { get; set; } = string.Empty; - /// - /// 自动保存 - /// - public string IsArchive { get; set; } = "1"; - /// - /// 链接 - /// - public string Url { get; set; } = string.Empty; - /// - /// 自动复制 - /// - public string AutoMaticallyCopy { get; set; } = "0"; - /// - /// 复制文本 - /// - public string Copy { get; set; } = string.Empty; - #endregion - - #region 公共方法 - /// - /// 设置链接 - /// - /// - /// - public BarkMessage SetUrl(string url) - { - this.Url = url; - return this; - } - /// - /// 设置保存,默认保存 - /// - /// - public BarkMessage SetArchive() - { - IsArchive = "1"; - return this; - } - /// - /// 设置不保存,默认保存 - /// - /// - public BarkMessage SetNotArchive() - { - IsArchive = "0"; - return this; - } - /// - /// 设置自动复制,默认不自动复制 - /// - /// - public BarkMessage SetAutoCopy() - { - this.AutoMaticallyCopy = "1"; - return this; - } - /// - /// 设置不自动复制,默认不自动复制 - /// - /// - public BarkMessage SetNotAutoCopy() - { - this.AutoMaticallyCopy = "1"; - return this; - } - /// - /// 设置自动拷贝的文本,默认拷贝全文 - /// - /// - /// - public BarkMessage SetCopyText(string text) - { - Copy = text; - return this; - } - #endregion - } - public class BarkAuth { + [InputTypeAttribte(1, "Sound", "声音", "1107")] + public string Sound { get; set; } - [InputTypeAttribte(0, "IsArchive", "自动保存", "1")] + [InputTypeAttribte(2, "IsArchive", "自动保存", "1或0")] public string IsArchive { get; set; } - [InputTypeAttribte(0, "AutoMaticallyCopy", "自动复制", "0")] + [InputTypeAttribte(3, "AutoMaticallyCopy", "自动复制", "1或0")] public string AutoMaticallyCopy { get; set; } - [InputTypeAttribte(0, "DeviceToken", "DeviceToken", "DeviceToken",false)] + [InputTypeAttribte(4, "DeviceKey", "DeviceKey", "DeviceKey", true, true)] + public string DeviceKey { get; set; } + + [InputTypeAttribte(5, "DeviceToken", "DeviceToken", "DeviceToken", true, true)] public string DeviceToken { get; set; } + [InputTypeAttribte(6, "SendUrl", "SendUrl", "SendUrl", true, true)] + public string SendUrl { get; set; } + + } - [SendMethodKey("3B6DE04D-A9EF-4C91-A151-60B7425C5AB2", "Bark(未完成)", Order = -1)] + [SendMethodKey("3B6DE04D-A9EF-4C91-A151-60B7425C5AB2", "Bark", Order = 6, Waring = "BARK通道勿手动添加,请使用APP添加BARK地址绑定")] public class BarkSendTemplate : SendTemplate { - private static readonly string Topic = "me.fin.bark"; - private static readonly string KeyID = "LH4T9V5U4R"; - private static readonly string TeamID = "5U8LBRXG3A"; + private static string KeyID; + + private static string TeamID; + private static CngKey SecretKey; - + public override BarkAuth Auth { get; set; } public override bool SendMessage(SendMessage message) - { - var barkMessage = new BarkMessage(message.Title, message.Data) - { - IsArchive = Auth.IsArchive, - AutoMaticallyCopy = Auth.AutoMaticallyCopy - }; - SendMesssage(barkMessage, Auth.DeviceToken); - - return false; - } - - private bool SendMesssage(BarkMessage barkMessage, string device_Tokne) { if (SecretKey == null) { - var authPath = Path.Combine(DBManager.Instance.Inotify_Data, "AuthKey_LH4T9V5U4R_5U8LBRXG3A.p8"); - var privateKeyContent = File.ReadAllText(authPath).Split('\n')[1]; - SecretKey = CngKey.Import(Convert.FromBase64String(privateKeyContent), CngKeyBlobFormat.Pkcs8PrivateBlob); + KeyID = SendCacheStore.GetSystemValue("barkKeyId"); + TeamID = SendCacheStore.GetSystemValue("barkTeamId"); + var privateKey = SendCacheStore.GetSystemValue("barkPrivateKey"); + var privateKeyContent = privateKey.Split('\n')[1]; + var decodeKey = Convert.FromBase64String(privateKeyContent); + SecretKey = CngKey.Import(decodeKey, CngKeyBlobFormat.Pkcs8PrivateBlob); } - if (barkMessage == null) + if (Auth.DeviceToken == null) return false; - if (device_Tokne == null) - return false; + var payload = CreatePayload(message); + var accessToken = CreateAccessToken(payload); + var result = CreatePush(payload, accessToken, Auth.DeviceToken); + return result; + + } + + private string CreatePayload(SendMessage message) + { var expiration = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var expirationSeconds = (long)expiration.TotalSeconds; var alert = new Dictionary(); - if (!string.IsNullOrEmpty(barkMessage.Body)) - alert.Add("body", barkMessage.Body); - if (!string.IsNullOrEmpty(barkMessage.Title)) - alert.Add("title", barkMessage.Title); + if (!string.IsNullOrEmpty(message.Data)) + alert.Add("body", message.Data); + if (!string.IsNullOrEmpty(message.Title)) + alert.Add("title", message.Title); var aps = new Dictionary { { "category", "Bark" }, - { "sound", "1107" }, + { "sound", Auth.Sound }, { "badge", "0" }, { "mutable-content", "1" }, { "alert", alert } @@ -184,65 +98,88 @@ namespace Inotify.Sends.Products var payload = new Dictionary { { "aps", aps }, - { "isarchive", barkMessage.IsArchive }, - { "automaticallycopy", barkMessage.AutoMaticallyCopy }, + { "isarchive", Auth.IsArchive }, + { "automaticallycopy", Auth.AutoMaticallyCopy }, { "iss", TeamID}, { "iat", expirationSeconds} }; - if (!string.IsNullOrEmpty(barkMessage.Url)) - payload.Add("url", barkMessage.Url); + if (!string.IsNullOrEmpty(message.Title)) + payload.Add("copy", message.Title); - if (!string.IsNullOrEmpty(barkMessage.Copy)) - payload.Add("copy", barkMessage.Copy); - - var headers = new - { - alg = "ES256", - kid = KeyID - }; - - var hearderString = JObject.FromObject(headers).ToString(); var payloadString = JObject.FromObject(payload).ToString(); - var accessToken = SignES256(SecretKey, hearderString, payloadString); - var data = Encoding.UTF8.GetBytes(payloadString); - var httpClient = new HttpClient(); - var requestMessage = new HttpRequestMessage - { - RequestUri = new Uri(string.Format("https://{0}:{1}/3/device/{2}", "api.development.push.apple.com", 443, device_Tokne)) - }; - requestMessage.Headers.Add("authorization", string.Format("bearer {0}", accessToken)); - requestMessage.Headers.Add("apns-id", Guid.NewGuid().ToString()); - requestMessage.Headers.Add("apns-expiration", "0"); - requestMessage.Headers.Add("apns-priority", "10"); - requestMessage.Headers.Add("apns-topic", Topic); - requestMessage.Method = HttpMethod.Post; - requestMessage.Content = new ByteArrayContent(data); - - var task = httpClient.SendAsync(requestMessage); - task.Wait(); - var responseMessage = task.Result; - if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK) - { - - return true; - } - - return true; + return payloadString; } - - private string SignES256(CngKey secretKey, string header, string payload) + private string CreateAccessToken(string payload) { - using ECDsaCng dsa = new ECDsaCng(secretKey) + using ECDsaCng dsa = new ECDsaCng(SecretKey) { HashAlgorithm = CngAlgorithm.Sha256 }; - var unsignedJwtData = Convert.ToBase64String(Encoding.UTF8.GetBytes(header)) + "." + Convert.ToBase64String(Encoding.UTF8.GetBytes(payload)); + var headers = JObject.FromObject(new + { + alg = "ES256", + kid = KeyID + }).ToString(); + + var unsignedJwtData = Convert.ToBase64String(Encoding.UTF8.GetBytes(headers)) + "." + Convert.ToBase64String(Encoding.UTF8.GetBytes(payload)); var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData)); return unsignedJwtData + "." + Convert.ToBase64String(signature); } + + private bool CreatePush(string payload, string accessToken, string device_Tokne) + { + try + { + var data = Encoding.UTF8.GetBytes(payload); + var request = new HttpRequestMessage + { + Version = new Version(2, 0), + RequestUri = new Uri($"https://api.development.push.apple.com:443/3/device/{device_Tokne}") + }; + request.Headers.Add("authorization", string.Format("bearer {0}", accessToken)); + request.Headers.Add("apns-id", Guid.NewGuid().ToString()); + request.Headers.Add("apns-expiration", "0"); + request.Headers.Add("apns-priority", "10"); + request.Headers.Add("apns-topic", "me.fin.bark"); + request.Method = HttpMethod.Post; + request.Content = new ByteArrayContent(data); + + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.Connection.Add("Keep-Alive"); + + var task = httpClient.SendAsync(request); + task.Wait(); + var responseMessage = task.Result; + if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK) + { + var _response_uuid = ""; + if (responseMessage.Headers.TryGetValues("apns-id", out IEnumerable values)) + { + _response_uuid = values.First(); + Console.WriteLine($"success: '{_response_uuid}'"); + return true; + } + else + return false; + } + else + { + var respoinseBody = responseMessage.Content.ReadAsStringAsync().Result; + var responseJson = JObject.Parse(respoinseBody); + var reason = responseJson.Value("reason"); + Console.WriteLine($"failure: '{reason}'"); + } + } + catch (Exception ex) + { + Console.WriteLine($"exception: '{ex.Message}'"); + } + + return false; + } } } diff --git a/Inotify/Sends/SendMessage.cs b/Inotify/Sends/SendMessage.cs index 7667e67..c943b47 100644 --- a/Inotify/Sends/SendMessage.cs +++ b/Inotify/Sends/SendMessage.cs @@ -9,5 +9,6 @@ namespace Inotify.Sends public string Token; public string Title; public string? Data; + public string? Key; } } diff --git a/Inotify/Sends/SendTaskManager.cs b/Inotify/Sends/SendTaskManager.cs index ecf2674..b4c1160 100644 --- a/Inotify/Sends/SendTaskManager.cs +++ b/Inotify/Sends/SendTaskManager.cs @@ -37,7 +37,6 @@ namespace Inotify.Sends private readonly Dictionary m_sendMethodTemplateTypes; - private SendTaskManager() { m_sendMessages = new BlockingCollection(); @@ -70,7 +69,6 @@ namespace Inotify.Sends m_analyseThread.Start(); } - public EventHandler OnMessageAdd; public EventHandler OnSendSucessed; @@ -152,7 +150,7 @@ namespace Inotify.Sends try { var message = m_sendMessages.Take(); - DBManager.Instance.GetAuth(message.Token, out SendAuthInfo[] sendAuthInfos); + DBManager.Instance.GetSendAuthInfos(message.Token, message.Key, out SendAuthInfo[] sendAuthInfos); foreach (var authInfo in sendAuthInfos) { var authData = authInfo.AuthData; @@ -212,7 +210,7 @@ namespace Inotify.Sends { var message = m_analyseMessages.Take(); var date = DateTime.Now.ToString("yyyyMMdd"); - var authData = DBManager.Instance.GetAuth(message.Token, out string temeplateId); + var authData = DBManager.Instance.GetSendAuthInfo(message.Token, out string temeplateId); if (temeplateId != null) { diff --git a/Inotify/Sends/SendTemplate.cs b/Inotify/Sends/SendTemplate.cs index 2de60ac..2e5f041 100644 --- a/Inotify/Sends/SendTemplate.cs +++ b/Inotify/Sends/SendTemplate.cs @@ -31,16 +31,25 @@ namespace Inotify.Sends public int Order; - public SendMethodKeyAttribute(string key, string name, bool open = true) + public string Waring; + + public SendMethodKeyAttribute(string key, string name, bool open = true, string waring = "") { Key = key; Name = name; Open = open; + Waring = waring; } } public class InputTypeValue { + + public InputTypeValue() + { + Show = true; + Readonly = false; + } public string? Name { get; set; } public string? Description { get; set; } public string? Default { get; set; } @@ -48,7 +57,11 @@ namespace Inotify.Sends public int? Order { get; set; } public string? Value { get; set; } - public bool Visuable { get; set; } + public string? Warning { get; set; } + + public bool Show { get; set; } + + public bool Readonly { get; set; } } public class InputTemeplate @@ -57,6 +70,7 @@ namespace Inotify.Sends public string? Type { get; set; } public string? Name { get; set; } public bool IsActive { get; set; } + public string Warning { get; set; } public string? AuthData { get; set; } public int? SendAuthId { get; set; } public List? Values { get; set; } @@ -112,7 +126,7 @@ namespace Inotify.Sends public InputTypeValue InputTypeData { get; set; } - private InputTypeAttribte(int order, string name, string description, string defaultValue, InputType type,bool visuable=true) + private InputTypeAttribte(int order, string name, string description, string defaultValue, InputType type,bool show=true,bool readOnly=false) { InputTypeData = new InputTypeValue { @@ -121,18 +135,19 @@ namespace Inotify.Sends Default = defaultValue, Order = order, Type = type, - Visuable=visuable + Show = show, + Readonly = readOnly }; } - public InputTypeAttribte(int order, string name, string description, string defaultValue, bool visuable = true) - : this(order, name, description, defaultValue, InputType.TEXT, visuable) + public InputTypeAttribte(int order, string name, string description, string defaultValue, bool show = true, bool readOnly = false) + : this(order, name, description, defaultValue, InputType.TEXT, show, readOnly) { } - public InputTypeAttribte(int order, string name, string description, bool defaultValue, bool visuable = true) - : this(order, name, description, "", InputType.CHECK, visuable) + public InputTypeAttribte(int order, string name, string description, bool defaultValue, bool show = true, bool readOnly = false) + : this(order, name, description, "", InputType.CHECK, show, readOnly) { InputTypeData.Default = defaultValue ? "是" : "否"; } @@ -156,7 +171,6 @@ namespace Inotify.Sends .SelectMany(e => e.GetCustomAttributes(typeof(InputTypeAttribte), false)) .Cast() .Select(e => e.InputTypeData) - .Where(e=>e.Visuable) .ToList(); var sendMethodKeyAttribute = this.GetType().GetCustomAttribute(); @@ -168,6 +182,7 @@ namespace Inotify.Sends Name = sendMethodKeyAttribute.Name, Type = sendMethodKeyAttribute.Name, Key = sendMethodKeyAttribute.Key, + Warning = sendMethodKeyAttribute.Waring, Values = values }; } diff --git a/Inotify/Startup.cs b/Inotify/Startup.cs index 9bf93a6..ad8a90d 100644 --- a/Inotify/Startup.cs +++ b/Inotify/Startup.cs @@ -20,6 +20,7 @@ using System.Net.Http; using System.Runtime.InteropServices; using System.Text; using System.Text.Encodings.Web; +using System.Text.RegularExpressions; using System.Text.Unicode; using System.Threading.Tasks; @@ -96,26 +97,63 @@ namespace Inotify public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - - app.UseStaticFiles(); - app.UseFileServer(); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } var options = new RewriteOptions(); - options.AddRewrite(@"api/(.*).send/(.*)/(.*)", "api/send?token=$1&title=$2&data=$3", true); - options.AddRewrite(@"api/(.*).send/(.*)", "api/send?token=$1&title=$2", true); - options.AddRewrite(@"\?act=(.*)/{.*}/(.*)/(.*)", "api/send?token=$1&title=$3&data=$4", true); - options.AddRewrite(@"\?act=(.*)/{.*}/(.*)", "api/send?token=$1&title=$3", true); + options.Add(rewriteContext => + { + Match match; + if (rewriteContext.HttpContext.Request.Path == "/") + { + var queryValue = rewriteContext.HttpContext.Request.QueryString.Value; + match = Regex.Match(queryValue, @"^\?act=(.*)/(.*)/(.*)/(.*)$"); + var groups = match.Groups; + if (match.Success) + { + rewriteContext.HttpContext.Request.Path = @"/api/send"; + rewriteContext.HttpContext.Request.QueryString = new QueryString($"?token={groups[1]}&key={groups[2]}&title={groups[3]}&date={groups[4]}"); + } + else + { + match = Regex.Match(queryValue, @"^\?act=(.*)/(.*)/(.*)$"); + if (match.Success) + { + rewriteContext.HttpContext.Request.Path = @"/api/send"; + rewriteContext.HttpContext.Request.QueryString = new QueryString($"?token={groups[1]}&key={groups[2]}&title={groups[3]}"); + } + else + { + match = Regex.Match(queryValue, @"^\?act=(.*)/(.*)$"); + if (match.Success) + { + rewriteContext.HttpContext.Request.Path = @"/api/send"; + rewriteContext.HttpContext.Request.QueryString = new QueryString($"?token={groups[1]}&key={groups[2]}"); + } + else if(rewriteContext.HttpContext.Request.QueryString.Value.StartsWith("?")) + { + rewriteContext.HttpContext.Request.Path = @"/info"; + rewriteContext.HttpContext.Request.QueryString = new QueryString(); + } + } + } + } + rewriteContext.Result = RuleResult.ContinueRules; + }); - //https://im.xpnas.com/?act=123456/ZtCLMPWQWtjJQpKmQS6hoV/ - + options.AddRewrite(@"^(.*).send/(.*)/(.*)", "api/send?token=$1&title=$2&data=$3", true); + options.AddRewrite(@"^(.*).send/(.*)", "api/send?token=$1&title=$2", true); + options.AddRewrite(@"^api/(.*).send/(.*)/(.*)", "api/send?token=$1&title=$2&data=$3", true); + options.AddRewrite(@"^api/(.*).send/(.*)", "api/send?token=$1&title=$2", true); app.UseRewriter(options); app.UseRouting(); + + app.UseStaticFiles(); + app.UseFileServer(); + app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => diff --git a/Inotify/ThridOauth/Service/GitHubLogin.cs b/Inotify/ThridOauth/Service/GitHubLogin.cs index afefbb0..f8080bc 100644 --- a/Inotify/ThridOauth/Service/GitHubLogin.cs +++ b/Inotify/ThridOauth/Service/GitHubLogin.cs @@ -26,7 +26,7 @@ namespace Inotify.ThridOauth.Service private readonly string _authorizeUrl; - public GitHubLogin(IHttpContextAccessor contextAccessor, IOptions options) : base( + public GitHubLogin(IHttpContextAccessor contextAccessor) : base( contextAccessor) { Credential = new CredentialSetting() diff --git a/README.md b/README.md index b23a072..7daedf3 100644 --- a/README.md +++ b/README.md @@ -22,30 +22,49 @@ - [x] 企业微信应用消息 - [x] 电报机器人消息 - [x] SMTP邮箱消息 +- [x] BARK - [ ] 钉钉群机器人 - [ ] 飞书群机器人 - [x] 自定义 -## 使用方法 - 1. Docker安装 - ``` - docker run --name=inotify -d -p 8000:80 -v inotify_data:/inotify_data --restart=always xpnas/inotify:latest - ``` +## 更新日志 + * V1.0 + * 支持企业微信应用、电报、SMTP消息 + * V2.0.0.1 + * 支持自定义Get、POST + * V2.0.0.2 + * 支持BARK + +## 使用方法 + 1. Docker安装 + * 稳定版V1.0 + ``` + docker run --name=inotify -d -p 8000:80 -v inotify_data:/inotify_data --restart=always xpnas/inotify:latest + ``` + * 开发版V2.0.0.2 + ``` + docker run --name=inotify -d -p 8000:80 -v inotify_data:/inotify_data --restart=always xpnas/inotify:master + ``` 2. 配置Nginx代理 - ``` - server - { - location / { proxy_pass http://127.0.0.1:8000; } - } - ``` - + ``` + server + { + location / { proxy_pass http://127.0.0.1:8000; } + } + ``` + 3. 进入`Github/Settings/Developer settings/OAuth Apps`创建应用 * 记录`Client ID`,创建`Client secrets` * `Authorization callback URL`回调地址填写https://{您的域名}/api/oauth/githubLogin 4. 使用`默认用户名admin,密码123456`登陆后台/全局参数,修改Github登陆的`应用ID`、`应用密钥`并启动登陆 5. 建议将`管理权限`的用户名设置成自己的github用户名,再使用Github登陆后,在用户管理页面`删除默认账号admin` +## BARK设置 + 1. 本项目依据Bark-Server接口规范实现了内置BARK服务端 + 2. 复制或扫码`消息验证\BARK授权`中的地址,填入BARK应用的服务器地址中,如`https://inotify.cf?act=6D474C0DB1474F19BD8F7342D570C0FC` + 3. BARK的APP会自动在本系统注册数据,记录将直接出现在`消息通道` + ## 系统截图 ![](../master/public/A.png) diff --git a/public/A.png b/public/A.png index 623052e..ad336ec 100644 Binary files a/public/A.png and b/public/A.png differ