Compare commits

...

3 Commits

Author SHA1 Message Date
duffyduck 724beba34a Release v0.0.0.16 2026-04-03 18:24:35 +02:00
duffyduck 65d3e911d0 Auto-reset mappings when address book is changed in profile editor
When editing a profile and switching to a different Starface
address book, the old contact mappings are invalid (different
Starface IDs). Now automatically clears mappings and shows a
notification. Custom address books are already listed as tags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:23:47 +02:00
duffyduck ab9c16c69a Fix contact creation: assign tag (address book) to new contacts
Starface requires every contact to be assigned to a tag.
- Load tag IDs when fetching address books (folder/all for central,
  folder/private for personal)
- Include tags array in POST /contacts body
- Debug log all discovered tags for troubleshooting

Important: Existing profiles need to reload address books (edit
profile -> load address books -> save) to pick up the tag IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:21:58 +02:00
5 changed files with 78 additions and 33 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
; Erfordert Inno Setup 6.x (https://jrsoftware.org/isinfo.php)
#define MyAppName "Starface Outlook Sync"
#define MyAppVersion "0.0.0.15"
#define MyAppVersion "0.0.0.16"
#define MyAppPublisher "HackerSoft - Hacker-Net Telekommunikation"
#define MyAppURL "https://www.hacker-net.de"
#define MyAppExeName "StarfaceOutlookSync.exe"
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
@@ -115,43 +116,63 @@ namespace StarfaceOutlookSync.Services
{
var books = new List<StarfaceAddressBook>();
books.Add(new StarfaceAddressBook
{
Type = "central",
Name = "Zentrales Adressbuch"
});
var userId = await GetCurrentUserIdAsync();
if (!string.IsNullOrEmpty(userId))
{
books.Add(new StarfaceAddressBook
{
Type = "user",
UserId = userId,
Name = "Persoenliches Adressbuch"
});
}
// Tags als virtuelle Adressbuecher
// Alle Tags laden - die Starface nutzt Tags als Adressbuch-Zuordnung
var allTags = new JArray();
try
{
var resp = await _http.GetAsync($"{_baseUrl}/contacts/tags");
if (resp.IsSuccessStatusCode)
{
var tags = JArray.Parse(await resp.Content.ReadAsStringAsync());
foreach (var tag in tags)
{
books.Add(new StarfaceAddressBook
{
Type = "tag",
TagId = tag["id"]?.ToString() ?? "",
Name = $"Tag: {tag["name"]}"
});
}
allTags = JArray.Parse(await resp.Content.ReadAsStringAsync());
OnDebug?.Invoke($"Gefundene Tags: {allTags.Count}");
foreach (var t in allTags)
OnDebug?.Invoke($" Tag: {t["name"]} (id: {t["id"]}, alias: {t["alias"]}, owner: {t["owner"]})");
}
}
catch { }
// Zentrales Adressbuch (folder/all)
var allTag = allTags.FirstOrDefault(t => t["name"]?.ToString() == "folder/all"
|| t["alias"]?.ToString()?.Contains("folder.all") == true);
books.Add(new StarfaceAddressBook
{
Type = "central",
TagId = allTag?["id"]?.ToString() ?? "",
Name = "Zentrales Adressbuch"
});
// Persoenliches Adressbuch (folder/private mit owner = userId)
var userId = await GetCurrentUserIdAsync();
if (!string.IsNullOrEmpty(userId))
{
var privateTag = allTags.FirstOrDefault(t =>
(t["name"]?.ToString() == "folder/private" || t["alias"]?.ToString()?.Contains("folder.private") == true)
&& t["owner"]?.ToString() == userId);
books.Add(new StarfaceAddressBook
{
Type = "user",
UserId = userId,
TagId = privateTag?["id"]?.ToString() ?? "",
Name = "Persoenliches Adressbuch"
});
}
// Alle weiteren Tags als Adressbuecher anbieten
foreach (var tag in allTags)
{
var tagName = tag["name"]?.ToString() ?? "";
// folder/all und folder/private bereits oben erfasst
if (tagName == "folder/all" || tagName == "folder/private") continue;
books.Add(new StarfaceAddressBook
{
Type = "tag",
TagId = tag["id"]?.ToString() ?? "",
Name = tagName
});
}
return books;
}
@@ -248,6 +269,16 @@ namespace StarfaceOutlookSync.Services
public async Task<UnifiedContact> CreateContactAsync(UnifiedContact contact, StarfaceAddressBook book)
{
var sfContact = MapToStarface(contact);
// Tag zuweisen - die Starface verlangt dass jeder Kontakt einem Tag zugeordnet ist
if (!string.IsNullOrEmpty(book.TagId))
{
sfContact["tags"] = new JArray
{
new JObject { ["id"] = book.TagId }
};
}
var query = "";
if (book.Type == "user" && !string.IsNullOrEmpty(book.UserId))
query = $"?userId={book.UserId}";
@@ -7,9 +7,9 @@
<AssemblyTitle>Starface Outlook Sync</AssemblyTitle>
<Company>HackerSoft - Hacker-Net Telekommunikation</Company>
<Product>Starface Outlook Sync</Product>
<Version>0.0.0.15</Version>
<AssemblyVersion>0.0.0.15</AssemblyVersion>
<FileVersion>0.0.0.15</FileVersion>
<Version>0.0.0.16</Version>
<AssemblyVersion>0.0.0.16</AssemblyVersion>
<FileVersion>0.0.0.16</FileVersion>
<Description>Synchronisiert Outlook-Kontakte mit Starface Telefonanlage</Description>
<Copyright>Stefan Hacker - HackerSoft</Copyright>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
+1 -1
View File
@@ -27,7 +27,7 @@ namespace StarfaceOutlookSync.UI
var lblVersion = new Label
{
Text = "Version 0.0.0.15",
Text = "Version 0.0.0.16",
Left = 0, Top = 56, Width = 340, Height = 20,
TextAlign = ContentAlignment.MiddleCenter,
ForeColor = Color.Gray
@@ -333,9 +333,23 @@ namespace StarfaceOutlookSync.UI
};
if (_isNew)
{
_pm.AddProfile(profile);
}
else
{
// Wenn Adressbuch gewechselt wurde, Mappings zuruecksetzen
if (_existingProfile.StarfaceAddressBook?.TagId != profile.StarfaceAddressBook?.TagId
|| _existingProfile.StarfaceAddressBook?.Type != profile.StarfaceAddressBook?.Type)
{
_pm.SaveMappings(profile.Id, new List<SyncMapping>());
profile.LastSync = "";
MessageBox.Show(
"Adressbuch wurde geaendert.\nSync-Zuordnungen wurden automatisch zurueckgesetzt.",
"Adressbuch geaendert", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
_pm.UpdateProfile(profile);
}
DialogResult = DialogResult.OK;
Close();