Compare commits

..

50 Commits

Author SHA1 Message Date
2eb90b095f Merge branch 'feature/waydroid' into 'main'
Feature/waydroid

See merge request fabinfra/fabaccess/borepin!90
2025-03-18 23:54:38 +01:00
b2bcaf9ac2 remove empty line, add comment 2025-03-18 23:53:05 +01:00
90ef10c90f adjust version to be non-static 2025-03-18 23:53:05 +01:00
e13432e8c1 small adjustments 2025-03-18 23:53:05 +01:00
464e8c0dc1 add install script for waydroid android emulator 2025-03-18 23:53:05 +01:00
bad1d86242 Merge branch 'feature/translation-de' into 'main'
Feature/translation de

See merge request fabinfra/fabaccess/borepin!89
2025-03-18 03:33:47 +01:00
ff9853b9d7 make german language work 2025-03-18 03:31:47 +01:00
cd166944c8 fix missing string 2025-03-18 02:33:59 +01:00
8f6fd44b38 add de lang translations 2025-03-17 23:42:27 +01:00
4404daac8b Merge branch 'main' into 'main'
some more small fixes for GTK build

See merge request fabinfra/fabaccess/borepin!88
2025-02-22 13:31:21 +00:00
e505d06495 some more small fixes for GTK build 2025-02-22 14:30:35 +01:00
0dd9e1b458 Merge branch 'main' into 'main'
Small fix for GTK build

See merge request fabinfra/fabaccess/borepin!87
2025-02-22 13:21:41 +00:00
f907d4d7e1 Merge branch borepin:main into main 2025-02-22 13:21:01 +00:00
7dcaabf1bb This leverages 6ec774944b and f8634837a4 2025-02-22 14:19:53 +01:00
e628493df8 Merge branch 'main' into 'main'
Add missing CHANGELOG.md from branch interfacer_release

See merge request fabinfra/fabaccess/borepin!86
2025-02-22 13:13:51 +00:00
483cc7204c Add missing CHANGELOG.md from branch interfacer_release 2025-02-22 14:13:01 +01:00
d39e0078d0 Merge branch 'vmario891-main-patch-29872' into 'main'
fix typo

See merge request fabinfra/fabaccess/borepin!83
2025-02-22 10:51:49 +00:00
9eb4dadadd fix typo 2025-02-22 10:51:19 +00:00
2986da785e Merge branch 'update-readme' into 'main'
Move documentation to official docs platform

See merge request fabinfra/fabaccess/borepin!85
2025-02-22 10:48:00 +00:00
68546cbe38 Move documentation to official docs platform 2025-02-22 10:46:24 +00:00
TheJoKlLa
2c71fc3949 Merge branch 'fix/changeconnetionhangup' into 'main'
Fixed: Hangup on change connection while connected

See merge request fabinfra/fabaccess/borepin!80
2023-02-28 12:27:20 +00:00
TheJoKlLa
6b46303607 Fixed: Hangup on change connection while connected 2023-02-28 13:21:22 +01:00
TheJoKlLa
c3fb9cd5fa Merge branch 'fix/unlock' into 'main'
Added: Command Link

See merge request fabinfra/fabaccess/borepin!79
2023-02-27 14:48:16 +00:00
TheJoKlLa
b7c47b5177 Added: Command Link 2023-02-27 15:42:24 +01:00
TheJoKlLa
7877d53f0b Merge branch 'feature/NFC' into 'main'
Feature/nfc

See merge request fabinfra/fabaccess/borepin!78
2023-02-27 01:48:10 +00:00
TheJoKlLa
75da7b6534 Added: Create Card on UWP 2023-02-27 02:42:18 +01:00
TheJoKlLa
f42bcfd3a1 Merge branch 'feature/opendoor' into feature/NFC 2023-02-27 01:21:30 +01:00
TheJoKlLa
d7e2a90a45 Added: Better Text 2023-02-27 01:19:26 +01:00
TheJoKlLa
84413c3b67 Added: new text to pages 2023-02-27 00:41:44 +01:00
TheJoKlLa
5c14dd9972 Added: iOS URL Schema 2023-02-26 21:07:00 +01:00
TheJoKlLa
825879a043 Fixed: Intent on Android 2023-02-26 19:50:58 +01:00
TheJoKlLa
c8c07e502b Open every NTAG and select by resource id 2023-02-24 16:45:28 +01:00
TheJoKlLa
bbbe3e7e2e Added: Unlock and Identify Button 2023-02-22 02:06:35 +01:00
TheJoKlLa
1a7e4ed236 Update API Schema 2023-02-21 22:49:30 +01:00
TheJoKlLa
b9bb50df87 Try to connect on NFC App Start with Server 2023-02-21 22:14:16 +01:00
TheJoKlLa
4790de0f78 Added: NFC Intent for Machine 2023-02-11 17:14:17 +01:00
TheJoKlLa
092081e82d Added: NTAG scan on Android 2023-02-11 14:54:55 +01:00
TheJoKlLa
c6d6153932 Activate API Communication 2023-02-03 00:16:47 +01:00
TheJoKlLa
b09c6dd507 Fixed FabFireCard 2023-02-02 22:26:06 +01:00
TheJoKlLa
b86ecf23a2 Added: Dummy 2023-02-02 05:26:48 +01:00
TheJoKlLa
d737faa989 Implement Scan Keys 2023-02-02 02:35:47 +01:00
TheJoKlLa
2f80a17c79 Fixed: Camera Rotation 2023-02-01 13:58:51 +01:00
TheJoKlLa
c425e05e8b Added: Create Card Page 2023-02-01 02:39:59 +01:00
TheJoKlLa
0e92447a3e Merge branch 'main' into feature/NFC 2023-01-31 15:25:13 +01:00
TheJoKlLa
2efeaefe18 Merge branch 'main' into feature/NFC 2023-01-31 15:24:40 +01:00
TheJoKlLa
7886fba5c7 Fixed: CapnProto Runtime 2023-01-31 01:20:59 +01:00
TheJoKlLa
0f8f424288 Fixed: NFCService 2023-01-31 00:46:33 +01:00
TheJoKlLa
df07210c7e Imported NFCService 2023-01-31 00:30:15 +01:00
TheJoKlLa
446dd850a3 More NFCService 2023-01-29 22:14:39 +01:00
TheJoKlLa
6e436b5c8c Start with NFCService 2023-01-29 16:55:07 +01:00
54 changed files with 3035 additions and 37695 deletions

View File

@ -17,10 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S22.Sasl", "external\SASL\S
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FabAccessAPI_Test", "FabAccessAPI_Test\FabAccessAPI_Test.csproj", "{1C85978A-9FC0-4064-8399-FA2455C5EC2A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FabAccessAPI_Test", "FabAccessAPI_Test\FabAccessAPI_Test.csproj", "{1C85978A-9FC0-4064-8399-FA2455C5EC2A}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "external\NFC\NFC\NFC.csproj", "{D53A98E8-48B5-4DCE-A98E-4623EE746E16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj", "{C587AAC3-50A7-4871-A50D-7880B6F24EF6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borepin_Test", "Borepin_Test\Borepin_Test.csproj", "{A959A406-91A5-4D81-B90D-EF022812D97D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borepin_Test", "Borepin_Test\Borepin_Test.csproj", "{A959A406-91A5-4D81-B90D-EF022812D97D}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EA0AA4A-A814-45A0-9EA7-E9147CCCCB6A}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EA0AA4A-A814-45A0-9EA7-E9147CCCCB6A}"
@ -32,6 +28,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.GTK", "Borepin\Borepin.GTK\Borepin.GTK.csproj", "{61D956D2-5819-4736-BBD8-AD8208DE6A62}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.GTK", "Borepin\Borepin.GTK\Borepin.GTK.csproj", "{61D956D2-5819-4736-BBD8-AD8208DE6A62}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "external\NFC\NFC\NFC.csproj", "{AC068302-655B-46B8-BC8A-971A3D685437}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC.PCSC", "external\NFC\NFC.PCSC\NFC.PCSC.csproj", "{6E2927DD-791F-48FA-96E1-696611FB38EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj", "{6CC49E97-4F07-43DE-A2AF-50914498A276}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -264,54 +266,6 @@ Global
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x64.Build.0 = Release|Any CPU {1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x64.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.ActiveCfg = Release|Any CPU {1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.Build.0 = Release|Any CPU {1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|ARM.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|iPhone.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|x64.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|x64.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|x86.ActiveCfg = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Debug|x86.Build.0 = Debug|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|Any CPU.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|ARM.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|ARM.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|iPhone.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|iPhone.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|x64.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|x64.Build.0 = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|x86.ActiveCfg = Release|Any CPU
{D53A98E8-48B5-4DCE-A98E-4623EE746E16}.Release|x86.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|ARM.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|iPhone.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|x64.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|x64.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|x86.ActiveCfg = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Debug|x86.Build.0 = Debug|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|Any CPU.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|ARM.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|ARM.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|iPhone.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|iPhone.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x64.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x64.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x86.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x86.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|ARM.ActiveCfg = Debug|Any CPU {A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|ARM.ActiveCfg = Debug|Any CPU
@ -360,6 +314,78 @@ Global
{61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x64.Build.0 = Release|Any CPU {61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x64.Build.0 = Release|Any CPU
{61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x86.ActiveCfg = Release|Any CPU {61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x86.ActiveCfg = Release|Any CPU
{61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x86.Build.0 = Release|Any CPU {61D956D2-5819-4736-BBD8-AD8208DE6A62}.Release|x86.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|ARM.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|ARM.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|iPhone.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|x64.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|x64.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|x86.ActiveCfg = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Debug|x86.Build.0 = Debug|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|Any CPU.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|ARM.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|ARM.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|iPhone.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|iPhone.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|x64.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|x64.Build.0 = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|x86.ActiveCfg = Release|Any CPU
{AC068302-655B-46B8-BC8A-971A3D685437}.Release|x86.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|ARM.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|iPhone.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|x64.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Debug|x86.Build.0 = Debug|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|Any CPU.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|ARM.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|ARM.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|iPhone.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|iPhone.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|x64.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|x64.Build.0 = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|x86.ActiveCfg = Release|Any CPU
{6E2927DD-791F-48FA-96E1-696611FB38EB}.Release|x86.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|ARM.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|iPhone.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|x64.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|x64.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|x86.ActiveCfg = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Debug|x86.Build.0 = Debug|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|Any CPU.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|ARM.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|ARM.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|iPhone.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|iPhone.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|x64.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|x64.Build.0 = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|x86.ActiveCfg = Release|Any CPU
{6CC49E97-4F07-43DE-A2AF-50914498A276}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -1,12 +1,23 @@
 using Android.App;
using Android.App; using Android.Content;
using Android.Content.PM; using Android.Content.PM;
using Android.OS; using Android.OS;
using AndroidX.AppCompat.App; using AndroidX.AppCompat.App;
namespace Borepin.Droid namespace Borepin.Droid
{ {
[Activity(Theme = "@style/MainTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] [Activity(Theme = "@style/MainTheme", LaunchMode = LaunchMode.SingleTask, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Exported = true)]
[IntentFilter(
new[]
{
"android.nfc.action.NDEF_DISCOVERED",
},
Categories = new[]
{
Intent.CategoryDefault
},
DataScheme = "fabaccess"
)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{ {
protected override void OnCreate(Bundle savedInstanceState) protected override void OnCreate(Bundle savedInstanceState)
@ -24,6 +35,15 @@ namespace Borepin.Droid
Xamarin.Forms.Forms.Init(this, savedInstanceState); Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App(new PlatformInitializer())); LoadApplication(new App(new PlatformInitializer()));
} }
protected override void OnNewIntent(Intent intent)
{
if(intent.Action == "android.nfc.action.NDEF_DISCOVERED")
{
intent.SetAction(Intent.ActionView);
}
base.OnNewIntent(intent);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{ {

View File

@ -7,9 +7,9 @@ namespace Borepin.Droid
[Application(Label = "FabAccess", Icon = "@mipmap/ic_launcher")] [Application(Label = "FabAccess", Icon = "@mipmap/ic_launcher")]
public class MainApplication : Application public class MainApplication : Application
{ {
public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
: base(javaReference, transfer)
{ {
} }
} }
} }

View File

@ -16,6 +16,7 @@ namespace Borepin.Droid
containerRegistry.Register<ISecretStorageService, SecretStorage>(); containerRegistry.Register<ISecretStorageService, SecretStorage>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.Register<IBrowserService, BrowserService>(); containerRegistry.Register<IBrowserService, BrowserService>();
// TODO containerRegistry.Register<INFCService, NFCService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }

View File

@ -1,9 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="org.fab_infra.fabaccess" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="org.fab_infra.fabaccess" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" /> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<application android:theme="@style/MainTheme" android:label="FabAccess" android:networkSecurityConfig="@xml/network_security_config"></application> <application android:theme="@style/MainTheme" android:label="FabAccess" android:networkSecurityConfig="@xml/network_security_config">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> </application>
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.BIND_NFC_SERVICE" />
</manifest> </manifest>

View File

@ -27,6 +27,7 @@ using Android.App;
// Add some common permissions, these can be removed if not needed // Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)] [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
[assembly: UsesPermission(Android.Manifest.Permission.Nfc)]
//#if DEBUG //#if DEBUG
//[assembly: Application(Debuggable=true)] //[assembly: Application(Debuggable=true)]

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\atk-sharp.dll</HintPath> <HintPath>..\..\..\..\..\..\..\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\atk-sharp.dll</HintPath>
</Reference> </Reference>
<Reference Include="DryIoc, Version=5.3.1.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL"> <Reference Include="DryIoc, Version=4.8.8.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.5.3.1\lib\net45\DryIoc.dll</HintPath> <HintPath>..\..\packages\DryIoc.dll.5.3.1\lib\net45\DryIoc.dll</HintPath>
</Reference> </Reference>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL"> <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">

View File

@ -12,7 +12,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" /> <assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.3.1.0" newVersion="5.3.1.0" /> <bindingRedirect oldVersion="0.0.0.0-4.8.8.0" newVersion="4.8.8.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="DryIoc.dll" version="5.3.1" targetFramework="net48" /> <package id="DryIoc.dll" version="4.8.8" targetFramework="net48" />
<package id="NLog" version="5.0.0" targetFramework="net46" />
<package id="OpenTK" version="3.2" targetFramework="net48" /> <package id="OpenTK" version="3.2" targetFramework="net48" />
<package id="Prism.Core" version="8.1.97" targetFramework="net48" /> <package id="Prism.Core" version="8.1.97" targetFramework="net48" />
<package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="net48" /> <package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="net48" />

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Borepin.UWP</RootNamespace> <RootNamespace>Borepin.UWP</RootNamespace>
<AssemblyName>Borepin.UWP</AssemblyName> <AssemblyName>Borepin.UWP</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage> <DefaultLanguage>en</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion> <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion> <TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
@ -17,8 +17,15 @@
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile> <EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled> <AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms> <AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundle>Always</AppxBundle>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateThumbprint>8BB0E624CAAF6E41BF034FE339F1AFA71F7ECBDE</PackageCertificateThumbprint>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -187,9 +194,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj"> <ProjectReference Include="..\..\external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj">
<Project>{c587aac3-50a7-4871-a50d-7880b6f24ef6}</Project> <Project>{6cc49e97-4f07-43de-a2af-50914498a276}</Project>
<Name>Capnp.Net.Runtime</Name> <Name>Capnp.Net.Runtime</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\external\NFC\NFC.PCSC\NFC.PCSC.csproj">
<Project>{6e2927dd-791f-48fa-96e1-696611fb38eb}</Project>
<Name>NFC.PCSC</Name>
</ProjectReference>
<ProjectReference Include="..\..\external\NFC\NFC\NFC.csproj">
<Project>{ac068302-655b-46b8-bc8a-971a3d685437}</Project>
<Name>NFC</Name>
</ProjectReference>
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj"> <ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj">
<Project>{3251FCE9-FEA3-4662-8BEB-636BE6732D48}</Project> <Project>{3251FCE9-FEA3-4662-8BEB-636BE6732D48}</Project>
<Name>FabAccessAPI</Name> <Name>FabAccessAPI</Name>
@ -199,6 +214,9 @@
<Name>Borepin</Name> <Name>Borepin</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Borepin.UWP_TemporaryKey.pfx" />
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>

View File

@ -8,8 +8,8 @@
<Identity <Identity
Name="f215b420-e2fb-4eb5-b168-f1b60fafa95b" Name="f215b420-e2fb-4eb5-b168-f1b60fafa95b"
Publisher="CN=2833ec12-ed0f-435b-ac4f-ae4d727a0c82" Publisher="CN=FabInfraDev"
Version="1.0.0.0" /> Version="1.0.1.0" />
<mp:PhoneIdentity PhoneProductId="ec0cc741-fd3e-485c-81be-68815c480690" PhonePublisherId="00000000-0000-0000-0000-000000000000"/> <mp:PhoneIdentity PhoneProductId="ec0cc741-fd3e-485c-81be-68815c480690" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
@ -54,6 +54,7 @@
<Capabilities> <Capabilities>
<Capability Name="internetClient" /> <Capability Name="internetClient" />
<Capability Name="privateNetworkClientServer"/> <Capability Name="privateNetworkClientServer"/>
<Capability Name="allJoyn"/> <uap:Capability Name="sharedUserCertificates"/>
<DeviceCapability Name="proximity"/>
</Capabilities> </Capabilities>
</Package> </Package>

View File

@ -5,6 +5,8 @@ using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using Borepin.Service; using Borepin.Service;
using Borepin.Service.Browser; using Borepin.Service.Browser;
using NFC.PCSC;
using NFC.Interfaces;
namespace Borepin.UWP namespace Borepin.UWP
{ {
@ -16,6 +18,7 @@ namespace Borepin.UWP
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.Register<IBrowserService, BrowserService>(); containerRegistry.Register<IBrowserService, BrowserService>();
containerRegistry.Register<INFCService, NFCService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }

View File

@ -42,5 +42,18 @@
<string>Light</string> <string>Light</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Please allow access to the camera to scan barcodes</string> <string>Please allow access to the camera to scan barcodes</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>FabAccess</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fabaccess</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
</dict> </dict>
</plist> </plist>

View File

@ -16,6 +16,7 @@ namespace Borepin.iOS
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.Register<IBrowserService, BrowserService>(); containerRegistry.Register<IBrowserService, BrowserService>();
// TODO containerRegistry.Register<INFCService, NFCService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }

View File

@ -13,6 +13,14 @@ using System;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using NLog; using NLog;
using Borepin.Service.ErrorMessage; using Borepin.Service.ErrorMessage;
using Prism.Navigation.Xaml;
using Prism.Navigation;
using Borepin.Service;
using FabAccessAPI;
using FabAccessAPI.Schema;
using System.Threading.Tasks;
using System.Collections.Generic;
using Prism.Services;
namespace Borepin namespace Borepin
{ {
@ -20,8 +28,8 @@ namespace Borepin
{ {
public App(IPlatformInitializer platformInitializer) : base(platformInitializer) public App(IPlatformInitializer platformInitializer) : base(platformInitializer)
{ {
var config = new NLog.Config.LoggingConfiguration(); NLog.Config.LoggingConfiguration config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); NLog.Targets.ConsoleTarget logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logconsole); config.AddRule(LogLevel.Trace, LogLevel.Fatal, logconsole);
LogManager.Configuration = config; LogManager.Configuration = config;
} }
@ -33,6 +41,52 @@ namespace Borepin
await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false); await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false);
} }
protected override async void OnAppLinkRequestReceived(Uri uri)
{
IPageDialogService pageDialogService = Container.Resolve<IPageDialogService>();
if (uri.LocalPath.StartsWith("/resource/", StringComparison.OrdinalIgnoreCase))
{
if (Container.IsRegistered<IAPIService>() && Container.IsRegistered<ILoginStorageService>())
{
string resource_id = uri.LocalPath.Remove(0, "/resource/".Length);
IAPIService apiService = Container.Resolve<IAPIService>();
IAPI api = apiService.GetAPI();
if (api.IsConnected)
{
Optional<Machine> optional = await api.Session.MachineSystem.Info.GetMachine(resource_id).ConfigureAwait(false);
if (optional.Just == null)
{
Device.BeginInvokeOnMainThread(async () =>
{
await pageDialogService.DisplayAlertAsync(Borepin.Resources.Text.TextResource.ALERT, Borepin.Resources.Text.TextResource.ALERT_ID, Borepin.Resources.Text.TextResource.OK).ConfigureAwait(false);
});
return;
}
Prism.Navigation.NavigationParameters parameters = new Prism.Navigation.NavigationParameters
{
{ "instance", optional.Just.Id },
};
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await Container.Resolve<INavigationService>().NavigateAsync("/MainPage/NavigationPage/MachineListPage/MachinePage", parameters).ConfigureAwait(false);
});
}
}
else
{
return;
}
}
}
protected override void RegisterTypes(IContainerRegistry containerRegistry) protected override void RegisterTypes(IContainerRegistry containerRegistry)
{ {
#region Register Basic Navigation #region Register Basic Navigation
@ -51,6 +105,7 @@ namespace Borepin
containerRegistry.RegisterForNavigation<UserListPage, UserListPageModel>(); containerRegistry.RegisterForNavigation<UserListPage, UserListPageModel>();
containerRegistry.RegisterForNavigation<UserPage, UserPageModel>(); containerRegistry.RegisterForNavigation<UserPage, UserPageModel>();
containerRegistry.RegisterForNavigation<CreateCardPage, CreateCardPageModel>();
containerRegistry.RegisterForNavigation<AddUserPage, AddUserPageModel>(); containerRegistry.RegisterForNavigation<AddUserPage, AddUserPageModel>();
containerRegistry.RegisterForNavigation<ProfilePage, ProfilePageModel>(); containerRegistry.RegisterForNavigation<ProfilePage, ProfilePageModel>();
#endregion #endregion

View File

@ -30,6 +30,9 @@
<None Remove="Helpers\**" /> <None Remove="Helpers\**" />
<None Remove="Properties\**" /> <None Remove="Properties\**" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="MultilingualResources\Borepin.de-DE.xlf" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="1.0.756"> <PackageReference Include="Meziantou.Analyzer" Version="1.0.756">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
@ -111,6 +114,9 @@
<EmbeddedResource Update="Page\AddUserPage.xaml"> <EmbeddedResource Update="Page\AddUserPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="Page\CreateCardPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\MachinePage.xaml"> <EmbeddedResource Update="Page\MachinePage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource> </EmbeddedResource>
@ -156,6 +162,10 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\external\NFC\NFC\NFC.csproj" />
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj" /> <ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<XliffResource Include="MultilingualResources\Borepin.de-DE.xlf" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,68 @@
using NFC.Helper;
using System;
using System.Globalization;
using System.Security.Cryptography;
namespace Borepin.Model
{
public class CardConfig
{
#region Constructors
public CardConfig()
{
PICCKey = GenerateEmptyKey();
APPKey = GenerateEmptyKey();
}
#endregion
#region Fields
public string UserID;
public byte[] PICCKey;
public byte[] APPKey;
public bool DoFormat;
public byte[] CardToken;
public byte[] MetaInfo;
public byte[] SpaceInfo;
#endregion
#region Mehtods
public string ConvertToString(byte[] array)
{
string data = HexConverter.ConvertToHexString(array);
data = data.ToUpper(CultureInfo.InvariantCulture);
for(int i = 2; i < data.Length; i += 3)
{
data = data.Insert(i, " ");
}
return data;
}
public byte[] ConvertFromString(string data)
{
data = data.Trim();
data = data.Replace(" ", "");
byte[] array = HexConverter.ConvertFromHexString(data);
return array;
}
public byte[] GenerateRandomKey()
{
byte[] key = ByteOperation.GenerateEmptyArray(16);
RNGCryptoServiceProvider cryptoProvider = new RNGCryptoServiceProvider();
cryptoProvider.GetBytes(key);
return key;
}
public byte[] GenerateEmptyKey()
{
return ByteOperation.GenerateEmptyArray(16);
}
#endregion
}
}

View File

@ -0,0 +1,63 @@
using Borepin.Page;
using FabAccessAPI.Schema;
using ImTools;
using NFC.Helper;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Borepin.Model
{
public class DESFireInterfaceDummy : User.ICardDESFireInterface
{
public Task Bind(IReadOnlyList<byte> token, IReadOnlyList<byte> auth_key, CancellationToken cancellationToken_ = default)
{
return Task.CompletedTask;
}
public void Dispose()
{
}
public Task<IReadOnlyList<byte>> GenCardToken(CancellationToken cancellationToken_ = default)
{
List<byte> token = new List<byte>();
token.AddRange(HexConverter.ConvertFromHexString("11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11".Replace(" ", "")));
return Task.FromResult((IReadOnlyList<byte>) token);
}
public Task<IReadOnlyList<byte>> GetMetaInfo(CancellationToken cancellationToken_ = default)
{
List<byte> data = new List<byte>();
data.AddRange(Encoding.ASCII.GetBytes("FABACCESS\0DESFIRE\01.0\0").Append((byte)0x00));
return Task.FromResult((IReadOnlyList<byte>)data);
}
public Task<IReadOnlyList<byte>> GetSpaceInfo(CancellationToken cancellationToken_ = default)
{
List<byte> data = new List<byte>();
data.AddRange(Encoding.ASCII.GetBytes("urn:fabaccess:lab:fabaccess_test").Append((byte)0x00));
return Task.FromResult((IReadOnlyList<byte>)data);
}
public Task<IReadOnlyList<IReadOnlyList<byte>>> GetTokenList(CancellationToken cancellationToken_ = default)
{
List<byte> token = new List<byte>();
token.AddRange(HexConverter.ConvertFromHexString("11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11".Replace(" ", "")));
IReadOnlyList<IReadOnlyList<byte>> list = new List<List<byte>>
{
token
};
return Task.FromResult(list);
}
public Task Unbind(IReadOnlyList<byte> token, CancellationToken cancellationToken_ = default)
{
return Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,116 @@
using Borepin.Service.ErrorMessage;
using NFC.Cards.NXP_MIFARE_DESFire;
using NFC.Cards.NXP_MIFARE_DESFire.Enums;
using NFC.Helper;
using NFC.Helper.Crypto;
using NFC.Interfaces;
using System;
using System.Text;
using ZXing.Aztec.Internal;
namespace Borepin.Model
{
public class FabFireCard
{
#region Private Fields
readonly INFCService _NFCService;
readonly IErrorMessageService _ErrorMessageService;
#endregion
#region Constructors
public FabFireCard(INFCService nfcService, IErrorMessageService errorMessageService)
{
_NFCService = nfcService;
_ErrorMessageService = errorMessageService;
}
#endregion
#region Methods
/// <summary>
/// Format Card
/// </summary>
/// <param name="readerID"></param>
/// <param name="cardConfig"></param>
public void FormatCard(string readerID, CardConfig cardConfig)
{
CipherKey PICCKey = new CipherKey(cardConfig.PICCKey, CipherType.TDES, 0x00);
_NFCService.Connect(readerID);
NXP_MIFARE_DESFire card = new NXP_MIFARE_DESFire(_NFCService);
card.SelectApplication(0x000000);
card.AuthenticateISO_DES(0x00, PICCKey._Key);
card.Format();
_NFCService.Disconnect();
}
/// <summary>
/// Create DESFire Card for V1.0
/// </summary>
/// <param name="readerID"></param>
/// <param name="cardConfig"></param>
/// <returns>Key #1 for authentication </returns>
public byte[] CreateCard(string readerID, CardConfig cardConfig)
{
CipherKey PICCKey = new CipherKey(cardConfig.PICCKey, CipherType.TDES, 0x00);
CipherKey MasterKey = new CipherKey(cardConfig.APPKey, CipherType.AES, 0x10);
CipherKey AuthKey = new CipherKey(cardConfig.GenerateRandomKey(), CipherType.AES, 0x10);
UInt32 AID = 0x464142;
CipherKey _Default_DESKey = new CipherKey(CipherType.TDES);
CipherKey _Default_AESKey = new CipherKey(CipherType.AES);
_NFCService.Connect(readerID);
NXP_MIFARE_DESFire card = new NXP_MIFARE_DESFire(_NFCService);
if (cardConfig.DoFormat)
{
card.AuthenticateISO_DES(0x00, _Default_DESKey._Key);
}
else
{
card.AuthenticateISO_DES(0x00, PICCKey._Key);
}
byte keySetting1 = card.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE);
byte keySetting2 = card.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x02);
card.CreateApplication(AID, keySetting1, keySetting2);
card.SelectApplication(AID);
card.AuthenticateISO_AES(0x00, _Default_AESKey._Key);
card.ChangeKey_AES(0x00, MasterKey._Key, MasterKey._KeyVersion);
card.AuthenticateISO_AES(0x00, MasterKey._Key);
card.ChangeOtherKey_AES(0x01, AuthKey._Key, _Default_AESKey._Key, AuthKey._KeyVersion);
UInt16 accessRights = card.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00);
card.CreateFile_Standard(0x01, FileCommunication.PLAIN, accessRights, (uint)cardConfig.MetaInfo.Length);
card.CreateFile_Standard(0x02, FileCommunication.PLAIN, accessRights, (uint)cardConfig.SpaceInfo.Length);
card.CreateFile_Standard(0x03, FileCommunication.PLAIN, accessRights, (uint)47);// TODO (uint)cardConfig.CardToken.Length);
card.WriteData(0x01, 0x00, cardConfig.MetaInfo);
card.WriteData(0x02, 0x00, cardConfig.SpaceInfo);
card.WriteData(0x03, 0x00, _TODOFixDataFileSize(cardConfig.CardToken));
_NFCService.Disconnect();
return AuthKey._Key;
}
/// <summary>
/// TODO implement GetFileInfo in DESFire
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private byte[] _TODOFixDataFileSize(byte[] data)
{
byte[] array = ByteOperation.GenerateEmptyArray(47);
data.CopyTo(array, 0);
return array;
}
#endregion
}
}

View File

@ -0,0 +1,14 @@
namespace Borepin.Model
{
public class KeyScan
{
public KeyScan(CardConfig cardConfig, KeyTypes keyType)
{
CardConfig = cardConfig;
KeyType = keyType;
}
public CardConfig CardConfig;
public KeyTypes KeyType;
}
}

View File

@ -0,0 +1,9 @@
namespace Borepin.Model
{
public enum KeyTypes
{
NONE,
PICC,
APP
};
}

View File

@ -21,6 +21,11 @@ namespace Borepin.Model
#region Methods #region Methods
public async Task LoadData() public async Task LoadData()
{ {
if(_Machine== null)
{
return;
}
//ID = _Machine.Id; //ID = _Machine.Id;
//Space = new SpaceVisualize(_Machine.Space); //Space = new SpaceVisualize(_Machine.Space);
Name = _Machine.Name; Name = _Machine.Name;
@ -75,6 +80,7 @@ namespace Borepin.Model
CanManage = !((ManageInterface_Proxy)_Machine.Manage).IsNull; CanManage = !((ManageInterface_Proxy)_Machine.Manage).IsNull;
CanAdmin = !((AdminInterface_Proxy)_Machine.Admin).IsNull; CanAdmin = !((AdminInterface_Proxy)_Machine.Admin).IsNull;
CanNotUseByPermission = State == MachineState.free && !CanUse; CanNotUseByPermission = State == MachineState.free && !CanUse;
IsLock = !((ProdInterface_Proxy)_Machine.Prodable).IsNull;
} }
#endregion #endregion
@ -197,6 +203,13 @@ namespace Borepin.Model
get => _CanNotUseByPermission; get => _CanNotUseByPermission;
set => SetProperty(ref _CanNotUseByPermission, value); set => SetProperty(ref _CanNotUseByPermission, value);
} }
private bool _IsLock;
public bool IsLock
{
get => _IsLock;
set => SetProperty(ref _IsLock, value);
}
#endregion #endregion
} }
} }

View File

@ -20,6 +20,11 @@ namespace Borepin.Model
#region LoadData #region LoadData
public Task LoadData() public Task LoadData()
{ {
if(_User == null)
{
return Task.CompletedTask;
}
//ID = _User.Id; //ID = _User.Id;
Username = _User.Username; Username = _User.Username;
//Space = new SpaceVisualize(_User.Space); //Space = new SpaceVisualize(_User.Space);

View File

@ -0,0 +1,475 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="de-DE" original="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="1.0.0.0" tool-company="Microsoft" />
</header>
<body>
<group id="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" datatype="resx">
<trans-unit id="AddServerProcess_AuthPlainPage_Login" translate="yes" xml:space="preserve">
<source>Login</source>
<target state="new">Login</target>
</trans-unit>
<trans-unit id="AddServerProcess_ChooseAuthTypePage_LoginCard" translate="yes" xml:space="preserve">
<source>Login with Card</source>
<target state="new">Login with Card</target>
</trans-unit>
<trans-unit id="AddServerProcess_ChooseAuthTypePage_LoginPassword" translate="yes" xml:space="preserve">
<source>Login with Password</source>
<target state="new">Login with Password</target>
</trans-unit>
<trans-unit id="AddServerProcess_ChooseAuthTypePage_Register" translate="yes" xml:space="preserve">
<source>Register</source>
<target state="new">Register</target>
</trans-unit>
<trans-unit id="AddServerProcess_ChooseAuthTypePage_SignIn" translate="yes" xml:space="preserve">
<source>Sign In:</source>
<target state="new">Sign In:</target>
</trans-unit>
<trans-unit id="AddServerProcess_ChooseAuthTypePage_SignUp" translate="yes" xml:space="preserve">
<source>Sign Up:</source>
<target state="new">Sign Up:</target>
</trans-unit>
<trans-unit id="AddServerProcess_SelectServerPage_Connect" translate="yes" xml:space="preserve">
<source>Connect to Server</source>
<target state="new">Connect to Server</target>
</trans-unit>
<trans-unit id="AddServerProcess_SelectServerPage_Info" translate="yes" xml:space="preserve">
<source>FabAccess is a decentralized machine management system, which means that it is designed to allow each Space to have its own dedicated server for managing its machines. If you want to connect to the FabAccess server for a specific Space, you will need to obtain the host address from that particular Space.
In addition to being able to connect to individual servers, FabAccess also allows you to add multiple servers to your account. This feature is especially useful for makers and innovators who have access to machines at multiple Spaces.</source>
<target state="new">FabAccess is a decentralized machine management system, which means that it is designed to allow each Space to have its own dedicated server for managing its machines. If you want to connect to the FabAccess server for a specific Space, you will need to obtain the host address from that particular Space.
In addition to being able to connect to individual servers, FabAccess also allows you to add multiple servers to your account. This feature is especially useful for makers and innovators who have access to machines at multiple Spaces.</target>
</trans-unit>
<trans-unit id="AddServerProcess_SelectServerPage_Placeholder" translate="yes" xml:space="preserve">
<source>test.fab-access.org</source>
<target state="new">test.fab-access.org</target>
</trans-unit>
<trans-unit id="AddServerProcess_SelectServerPage_TryConnection" translate="yes" xml:space="preserve">
<source>Trying to connect to the server</source>
<target state="new">Trying to connect to the server</target>
</trans-unit>
<trans-unit id="AddUserPage_AddUser" translate="yes" xml:space="preserve">
<source>Add User</source>
<target state="new">Add User</target>
</trans-unit>
<trans-unit id="ALERT" translate="yes" xml:space="preserve">
<source>Alert</source>
<target state="new">Alert</target>
</trans-unit>
<trans-unit id="ALERT_AddressInvalid" translate="yes" xml:space="preserve">
<source>Server address is invaild.</source>
<target state="new">Server address is invaild.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_AddUserFailed" translate="yes" xml:space="preserve">
<source>Add User failed.</source>
<target state="new">Add User failed.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_AuthFailed" translate="yes" xml:space="preserve">
<source>Authentication failed.</source>
<target state="new">Authentication failed.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Title</note>
</trans-unit>
<trans-unit id="ALERT_AuthServer" translate="yes" xml:space="preserve">
<source>Unable to authenticate to server.</source>
<target state="new">Unable to authenticate to server.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_BadMechanism" translate="yes" xml:space="preserve">
<source>SASL Mechanism is not supported.</source>
<target state="new">SASL Mechanism is not supported.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_ConnectionFailed" translate="yes" xml:space="preserve">
<source>Connection failed.</source>
<target state="new">Connection failed.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Title</note>
</trans-unit>
<trans-unit id="ALERT_ConnectionTimeout" translate="yes" xml:space="preserve">
<source>Connection time exceeded.</source>
<target state="new">Connection time exceeded.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_CredentialsInvalid" translate="yes" xml:space="preserve">
<source>Credentials are invalid.</source>
<target state="new">Credentials are invalid.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_DuplicateConnection" translate="yes" xml:space="preserve">
<source>Connection already exist. Please delete old Connection before adding the new Connection.</source>
<target state="new">Connection already exist. Please delete old Connection before adding the new Connection.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_ID" translate="yes" xml:space="preserve">
<source>ID is invalid.</source>
<target state="new">ID is invalid.</target>
</trans-unit>
<trans-unit id="ALERT_PasswordInvalid" translate="yes" xml:space="preserve">
<source>Password is invalid.</source>
<target state="new">Password is invalid.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_QRInvalid" translate="yes" xml:space="preserve">
<source>QR Code is invalid</source>
<target state="new">QR Code is invalid</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_SASLAuth" translate="yes" xml:space="preserve">
<source>SASL Authentication failed</source>
<target state="new">SASL Authentication failed</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_TLSInvalid" translate="yes" xml:space="preserve">
<source>TLS certificate is invalid.</source>
<target state="new">TLS certificate is invalid.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_UnableServer" translate="yes" xml:space="preserve">
<source>Unable to connect to server.</source>
<target state="new">Unable to connect to server.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_UnexpectedError" translate="yes" xml:space="preserve">
<source>Unexpected Error.</source>
<target state="new">Unexpected Error.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_UserExist" translate="yes" xml:space="preserve">
<source>User already exist.</source>
<target state="new">User already exist.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="ALERT_UsernameInvalid" translate="yes" xml:space="preserve">
<source>Username is invalid.</source>
<target state="new">Username is invalid.</target>
<note from="MultilingualBuild" annotates="source" priority="2">Message Content</note>
</trans-unit>
<trans-unit id="Bionade" translate="yes" xml:space="preserve">
<source>It's Bionade!</source>
<target state="new">It's Bionade!</target>
</trans-unit>
<trans-unit id="BUILD" translate="yes" xml:space="preserve">
<source>Build</source>
<target state="new">Build</target>
</trans-unit>
<trans-unit id="CANCEL" translate="yes" xml:space="preserve">
<source>Cancel</source>
<target state="new">Cancel</target>
</trans-unit>
<trans-unit id="CONFIRM" translate="yes" xml:space="preserve">
<source>Confirm</source>
<target state="new">Confirm</target>
</trans-unit>
<trans-unit id="ConnectionStatus_Connecting" translate="yes" xml:space="preserve">
<source>Connecting to Server</source>
<target state="new">Connecting to Server</target>
</trans-unit>
<trans-unit id="ConnectionStatus_NoConnection" translate="yes" xml:space="preserve">
<source>No Connection to Server</source>
<target state="new">No Connection to Server</target>
</trans-unit>
<trans-unit id="ConnectionStatus_NotConnected" translate="yes" xml:space="preserve">
<source>Please select a Server.</source>
<target state="new">Please select a Server.</target>
</trans-unit>
<trans-unit id="DELETE" translate="yes" xml:space="preserve">
<source>Delete</source>
<target state="new">Delete</target>
</trans-unit>
<trans-unit id="DIALOG_DeleteServer" translate="yes" xml:space="preserve">
<source>Delete Server</source>
<target state="new">Delete Server</target>
</trans-unit>
<trans-unit id="DIALOG_DeleteServerConfirm" translate="yes" xml:space="preserve">
<source>Do you really want to delete this Server?</source>
<target state="new">Do you really want to delete this Server?</target>
</trans-unit>
<trans-unit id="DIALOG_DeleteUser" translate="yes" xml:space="preserve">
<source>Delete User</source>
<target state="new">Delete User</target>
</trans-unit>
<trans-unit id="DIALOG_DeleteUserConfirm" translate="yes" xml:space="preserve">
<source>Do you really want to delete this User?</source>
<target state="new">Do you really want to delete this User?</target>
</trans-unit>
<trans-unit id="FABACCESS" translate="yes" xml:space="preserve">
<source>FabAccess</source>
<target state="new">FabAccess</target>
</trans-unit>
<trans-unit id="HOST" translate="yes" xml:space="preserve">
<source>Host</source>
<target state="new">Host</target>
</trans-unit>
<trans-unit id="InUseByMe" translate="yes" xml:space="preserve">
<source>In Use By Me</source>
<target state="new">In Use By Me</target>
</trans-unit>
<trans-unit id="MACHINE" translate="yes" xml:space="preserve">
<source>Machine</source>
<target state="new">Machine</target>
</trans-unit>
<trans-unit id="MachinePage_CanNotUseByPermission" translate="yes" xml:space="preserve">
<source>You are not currently authorized to use this machine.
Please speak with the staff at the Space to receive the necessary training and authorization.</source>
<target state="new">You are not currently authorized to use this machine.
Please speak with the staff at the Space to receive the necessary training and authorization.</target>
</trans-unit>
<trans-unit id="MachinePage_CurrentUser" translate="yes" xml:space="preserve">
<source>Current User:</source>
<target state="new">Current User:</target>
</trans-unit>
<trans-unit id="MachinePage_ForceBlock" translate="yes" xml:space="preserve">
<source>Block Machine</source>
<target state="new">Block Machine</target>
</trans-unit>
<trans-unit id="MachinePage_ForceDisable" translate="yes" xml:space="preserve">
<source>Disable Machine</source>
<target state="new">Disable Machine</target>
</trans-unit>
<trans-unit id="MachinePage_ForceFree" translate="yes" xml:space="preserve">
<source>Free Machine</source>
<target state="new">Free Machine</target>
</trans-unit>
<trans-unit id="MachinePage_GiveBack" translate="yes" xml:space="preserve">
<source>GiveBack</source>
<target state="new">GiveBack</target>
</trans-unit>
<trans-unit id="MachinePage_Identify" translate="yes" xml:space="preserve">
<source>Identify</source>
<target state="new">Identify</target>
</trans-unit>
<trans-unit id="MachinePage_LastUser" translate="yes" xml:space="preserve">
<source>Last User:</source>
<target state="new">Last User:</target>
</trans-unit>
<trans-unit id="MachinePage_ManageMachine" translate="yes" xml:space="preserve">
<source>Manage Machine:</source>
<target state="new">Manage Machine:</target>
</trans-unit>
<trans-unit id="MachinePage_OpenWiki" translate="yes" xml:space="preserve">
<source>Open Wiki</source>
<target state="new">Open Wiki</target>
</trans-unit>
<trans-unit id="MachinePage_Unlock" translate="yes" xml:space="preserve">
<source>Unlock</source>
<target state="new">Unlock</target>
</trans-unit>
<trans-unit id="MachinePage_Use" translate="yes" xml:space="preserve">
<source>Use</source>
<target state="new">Use</target>
</trans-unit>
<trans-unit id="MainPage_Build" translate="yes" xml:space="preserve">
<source>Build</source>
<target state="new">Build</target>
</trans-unit>
<trans-unit id="MainPage_Machines" translate="yes" xml:space="preserve">
<source>Machines</source>
<target state="new">Machines</target>
</trans-unit>
<trans-unit id="MainPage_Profile" translate="yes" xml:space="preserve">
<source>My Profile</source>
<target state="new">My Profile</target>
</trans-unit>
<trans-unit id="MainPage_Servers" translate="yes" xml:space="preserve">
<source>Servers</source>
<target state="new">Servers</target>
</trans-unit>
<trans-unit id="MainPage_Users" translate="yes" xml:space="preserve">
<source>Users</source>
<target state="new">Users</target>
</trans-unit>
<trans-unit id="MainPage_Version" translate="yes" xml:space="preserve">
<source>Version</source>
<target state="new">Version</target>
</trans-unit>
<trans-unit id="OK" translate="yes" xml:space="preserve">
<source>Ok</source>
<target state="new">Ok</target>
</trans-unit>
<trans-unit id="OR" translate="yes" xml:space="preserve">
<source>or</source>
<target state="new">or</target>
</trans-unit>
<trans-unit id="PASSWORD" translate="yes" xml:space="preserve">
<source>Password</source>
<target state="new">Password</target>
</trans-unit>
<trans-unit id="ProfilePage_ChangePassword" translate="yes" xml:space="preserve">
<source>Change Password</source>
<target state="new">Change Password</target>
</trans-unit>
<trans-unit id="ProfilePage_NewPassword" translate="yes" xml:space="preserve">
<source>New Password</source>
<target state="new">New Password</target>
</trans-unit>
<trans-unit id="ProfilePage_OldPassword" translate="yes" xml:space="preserve">
<source>Old Password</source>
<target state="new">Old Password</target>
</trans-unit>
<trans-unit id="ProfilePage_UpdatePassword" translate="yes" xml:space="preserve">
<source>Update Password</source>
<target state="new">Update Password</target>
</trans-unit>
<trans-unit id="SCANQR" translate="yes" xml:space="preserve">
<source>Scan QR-Code</source>
<target state="new">Scan QR-Code</target>
</trans-unit>
<trans-unit id="ServerListPage_ActiveConnection" translate="yes" xml:space="preserve">
<source>Active Connection</source>
<target state="new">Active Connection</target>
</trans-unit>
<trans-unit id="ServerListPage_ConnectToNewServer" translate="yes" xml:space="preserve">
<source>Connect to new Server</source>
<target state="new">Connect to new Server</target>
</trans-unit>
<trans-unit id="ServerListPage_LastConnection" translate="yes" xml:space="preserve">
<source>Last Connections</source>
<target state="new">Last Connections</target>
</trans-unit>
<trans-unit id="ServerPageModel_ConnectionFailed" translate="yes" xml:space="preserve">
<source>Connection failed</source>
<target state="new">Connection failed</target>
</trans-unit>
<trans-unit id="ServerPage_Connect" translate="yes" xml:space="preserve">
<source>Connect</source>
<target state="new">Connect</target>
</trans-unit>
<trans-unit id="ServerPage_DefaultText" translate="yes" xml:space="preserve">
<source>You can set a server as the default server and then the app will automatically connect to that server upon startup.</source>
<target state="new">You can set a server as the default server and then the app will automatically connect to that server upon startup.</target>
</trans-unit>
<trans-unit id="ServerPage_Disconnect" translate="yes" xml:space="preserve">
<source>Disconnect</source>
<target state="new">Disconnect</target>
</trans-unit>
<trans-unit id="ServerPage_IsDefault" translate="yes" xml:space="preserve">
<source>This connection has been set as the default and FabAccess will automatically connect to this server upon startup.</source>
<target state="new">This connection has been set as the default and FabAccess will automatically connect to this server upon startup.</target>
</trans-unit>
<trans-unit id="ServerPage_SetDefault" translate="yes" xml:space="preserve">
<source>Set as Default Connection</source>
<target state="new">Set as Default Connection</target>
</trans-unit>
<trans-unit id="SetUpProcess_ScanPage_Button" translate="yes" xml:space="preserve">
<source>Login to your Space</source>
<target state="new">Login to your Space</target>
</trans-unit>
<trans-unit id="SetUpProcess_WelcomePage_Button" translate="yes" xml:space="preserve">
<source>Begin working</source>
<target state="new">Begin working</target>
</trans-unit>
<trans-unit id="SetUpProcess_WelcomePage_Text" translate="yes" xml:space="preserve">
<source>FabAccess is a machine management system designed for makerspaces, fablab and other collaborative workspaces.
With FabAccess, you can access and schedule machines, manage users and receive real-time updates on machine status and usage. The platform provides a decentralized solution for managing and connecting to machines across different Spaces, making it easier for users to collaborate and innovate together.</source>
<target state="new">FabAccess is a machine management system designed for makerspaces, fablab and other collaborative workspaces.
With FabAccess, you can access and schedule machines, manage users and receive real-time updates on machine status and usage. The platform provides a decentralized solution for managing and connecting to machines across different Spaces, making it easier for users to collaborate and innovate together.</target>
</trans-unit>
<trans-unit id="SetUpProcess_WelcomePage_Title" translate="yes" xml:space="preserve">
<source>Welcome to FabAccess</source>
<target state="new">Welcome to FabAccess</target>
</trans-unit>
<trans-unit id="StartPage_Connecting" translate="yes" xml:space="preserve">
<source>Connecting to Server</source>
<target state="new">Connecting to Server</target>
</trans-unit>
<trans-unit id="StartPage_Starting" translate="yes" xml:space="preserve">
<source>Starting App</source>
<target state="new">Starting App</target>
</trans-unit>
<trans-unit id="TITLE_AddUser" translate="yes" xml:space="preserve">
<source>Add User</source>
<target state="new">Add User</target>
</trans-unit>
<trans-unit id="TITLE_ConnectToServer" translate="yes" xml:space="preserve">
<source>Connect to Server</source>
<target state="new">Connect to Server</target>
</trans-unit>
<trans-unit id="TITLE_Machine" translate="yes" xml:space="preserve">
<source>Machine</source>
<target state="new">Machine</target>
</trans-unit>
<trans-unit id="TITLE_Machines" translate="yes" xml:space="preserve">
<source>Machines</source>
<target state="new">Machines</target>
</trans-unit>
<trans-unit id="TITLE_Profile" translate="yes" xml:space="preserve">
<source>My Profile</source>
<target state="new">My Profile</target>
</trans-unit>
<trans-unit id="TITLE_Server" translate="yes" xml:space="preserve">
<source>Server</source>
<target state="new">Server</target>
</trans-unit>
<trans-unit id="TITLE_Servers" translate="yes" xml:space="preserve">
<source>Servers</source>
<target state="new">Servers</target>
</trans-unit>
<trans-unit id="TITLE_Settings" translate="yes" xml:space="preserve">
<source>Settings</source>
<target state="new">Settings</target>
</trans-unit>
<trans-unit id="TITLE_User" translate="yes" xml:space="preserve">
<source>User</source>
<target state="new">User</target>
</trans-unit>
<trans-unit id="TITLE_Users" translate="yes" xml:space="preserve">
<source>Users</source>
<target state="new">Users</target>
</trans-unit>
<trans-unit id="Uncategorised" translate="yes" xml:space="preserve">
<source>Uncategorised</source>
<target state="new">Uncategorised</target>
</trans-unit>
<trans-unit id="UserListPage_AddUser" translate="yes" xml:space="preserve">
<source>Add new User</source>
<target state="new">Add new User</target>
</trans-unit>
<trans-unit id="UserListPage_Search" translate="yes" xml:space="preserve">
<source>Search User</source>
<target state="new">Search User</target>
</trans-unit>
<trans-unit id="UserListPage_SearchUser" translate="yes" xml:space="preserve">
<source>Search Username ...</source>
<target state="new">Search Username ...</target>
</trans-unit>
<trans-unit id="USERNAME" translate="yes" xml:space="preserve">
<source>Username</source>
<target state="new">Username</target>
</trans-unit>
<trans-unit id="UserPage_ChangePassword" translate="yes" xml:space="preserve">
<source>Update Password</source>
<target state="new">Update Password</target>
</trans-unit>
<trans-unit id="UserPage_CreateCard" translate="yes" xml:space="preserve">
<source>Create new FabFire Card</source>
<target state="new">Create new FabFire Card</target>
</trans-unit>
<trans-unit id="UserPage_NewPassword" translate="yes" xml:space="preserve">
<source>New Password</source>
<target state="new">New Password</target>
</trans-unit>
<trans-unit id="UserPage_UnbindCard" translate="yes" xml:space="preserve">
<source>Unbind FabFire Card</source>
<target state="new">Unbind FabFire Card</target>
</trans-unit>
<trans-unit id="UserPage_UpdatePassword" translate="yes" xml:space="preserve">
<source>Force Password Update</source>
<target state="new">Force Password Update</target>
</trans-unit>
<trans-unit id="VERSION" translate="yes" xml:space="preserve">
<source>Version</source>
<target state="new">Version</target>
</trans-unit>
<trans-unit id="YAY" translate="yes" xml:space="preserve">
<source>YAY</source>
<target state="new">YAY</target>
</trans-unit>
</group>
</body>
</file>
</xliff>

View File

@ -13,7 +13,8 @@
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_TryConnection}" IsVisible="{Binding TestConnection}" Style="{StaticResource Style_Label_Text_Center}"/>
<ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="{x:Static resource_text:TextResource.USERNAME}" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.USERNAME}" Style="{StaticResource Style_Label_Property_Title}"></Label>

View File

@ -13,7 +13,7 @@
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_SignIn}" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_SignIn}" Style="{StaticResource Style_Label_Property_Title}"></Label>

View File

@ -12,21 +12,24 @@
</ContentPage.Resources> </ContentPage.Resources>
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout>
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_TryConnection}" IsVisible="{Binding TestConnection}" Style="{StaticResource Style_Label_Text_Center}"/>
<ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="{x:Static resource_text:TextResource.HOST}" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.HOST}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Entry Text="{Binding Host}" Keyboard="Url" IsSpellCheckEnabled="false"/> <Entry Text="{Binding Host}" Placeholder="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Placeholder}" PlaceholderColor="{StaticResource SecondColor}" Keyboard="Url" IsSpellCheckEnabled="false"/>
<Button Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Connect}" Command="{Binding ConnectToServerCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Connect}" Command="{Binding ConnectToServerCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}"> <Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible> <Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean" <OnPlatform x:TypeArguments="x:Boolean">
iOS="true" <On Platform="iOS" Value="True" />
Android="true"/> <On Platform="Android" Value="True" />
<On Platform="UWP" Value="False" />
</OnPlatform>
</Button.IsVisible> </Button.IsVisible>
</Button> </Button>
<Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Info}"></Label> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Info}" Margin="0, 20, 0, 0"></Label>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.CreateCardPage"
xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
xmlns:views="clr-namespace:Borepin.View"
Title="Create Card">
<NavigationPage.TitleView>
<Button Text="Refresh" HorizontalOptions="End" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}" Command="{Binding RefreshCommand}"/>
</NavigationPage.TitleView>
<ContentPage.Resources>
<ResourceDictionary>
<converters:AllTrueBoolConverter x:Key="AllTrueBoolConverter"/>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<views:ConnectionStateView/>
<StackLayout>
<StackLayout.IsVisible>
<MultiBinding Converter="{StaticResource AllTrueBoolConverter}">
<Binding Path="IsBusy" Converter="{StaticResource InvertBoolConverter}"/>
<Binding Path="IsConnected" />
</MultiBinding>
</StackLayout.IsVisible>
<Label Text="NFC Reader" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Picker ItemsSource="{Binding ReaderIDs}" SelectedItem="{Binding ReaderID}"></Picker>
<Label Text="PICC Key" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Entry Grid.Column="0" Text="{Binding PICCKey}" IsSpellCheckEnabled="false"/>
<Button Grid.Column="2" Text="Scan QR-Code" Command="{Binding ScanPICCKeyCommand}" Style="{StaticResource Style_Button_Primary}" IsVisible="False"/>
</Grid>
<Label Text="Application Key" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Entry Grid.Column="0" Text="{Binding APPKey}" IsSpellCheckEnabled="false"/>
<Button Grid.Column="1" Text="Random" Command="{Binding RandomAPPKeyCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Grid.Column="2" Text="Scan QR-Code" Command="{Binding ScanAPPKeyCommand}" Style="{StaticResource Style_Button_Primary}" IsVisible="False"/>
</Grid>
<StackLayout Orientation="Horizontal">
<CheckBox IsChecked="{Binding FormatCard}"/>
<Label Text="Format Card" VerticalOptions="Center"/>
</StackLayout>
<Button Text="Create Card" Command="{Binding CreateCardCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Page
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CreateCardPage : ContentPage
{
public CreateCardPage()
{
InitializeComponent();
}
}
}

View File

@ -29,12 +29,14 @@
</MultiBinding> </MultiBinding>
</StackLayout.IsVisible> </StackLayout.IsVisible>
<Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}"> <Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible> <Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean" <OnPlatform x:TypeArguments="x:Boolean">
iOS="True" <On Platform="iOS" Value="True" />
Android="True"/> <On Platform="Android" Value="True" />
</Button.IsVisible> <On Platform="UWP" Value="False" />
</Button> </OnPlatform>
</Button.IsVisible>
</Button>
<ListView ItemsSource="{Binding MachineListItemViewModel_List}" SelectionMode="None" SeparatorColor="Transparent" IsGroupingEnabled="True" GroupDisplayBinding="{Binding Category}"> <ListView ItemsSource="{Binding MachineListItemViewModel_List}" SelectionMode="None" SeparatorColor="Transparent" IsGroupingEnabled="True" GroupDisplayBinding="{Binding Category}">
<ListView.GroupHeaderTemplate> <ListView.GroupHeaderTemplate>
<DataTemplate> <DataTemplate>

View File

@ -43,15 +43,23 @@
<Label Text="{Binding MachineItem.CurrentUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/> <Label Text="{Binding MachineItem.CurrentUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout> </StackLayout>
<Button Text="{x:Static resource_text:TextResource.MachinePage_Use}" IsVisible="{Binding MachineItem.CanUse}" Command="{Binding UseMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <StackLayout>
<Label Text="{x:Static resource_text:TextResource.MachinePage_CanNotUseByPermission}" IsVisible="{Binding MachineItem.CanNotUseByPermission}" Style="{StaticResource Style_Label_Text_Center}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_Use}" IsVisible="{Binding MachineItem.CanUse}" Command="{Binding UseMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="{x:Static resource_text:TextResource.MachinePage_GiveBack}" IsVisible="{Binding MachineItem.CanInUse}" Command="{Binding GiveBackMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_CanNotUseByPermission}" IsVisible="{Binding MachineItem.CanNotUseByPermission}" Style="{StaticResource Style_Label_Text_Center}" TextColor="{StaticResource FourthColor}"/>
<Button VerticalOptions="End" Text="{x:Static resource_text:TextResource.MachinePage_OpenWiki}" IsVisible="{Binding MachineItem.Wiki, Converter={StaticResource IsNotNullBoolConverter}}" Command="{Binding OpenWikiCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_GiveBack}" IsVisible="{Binding MachineItem.CanInUse}" Command="{Binding GiveBackMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
<StackLayout Grid.Row="2" VerticalOptions="End" IsVisible="{Binding MachineItem.CanManage}"> </StackLayout>
<StackLayout Margin="0,10,0,0" IsVisible="{Binding MachineItem.IsLock}">
<Button Text="{x:Static resource_text:TextResource.MachinePage_Unlock}" Command="{Binding UnlockLockCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="{x:Static resource_text:TextResource.MachinePage_Identify}" Command="{Binding IdentifyLockCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
<Button VerticalOptions="End" Text="{x:Static resource_text:TextResource.MachinePage_OpenWiki}" IsVisible="{Binding MachineItem.Wiki, Converter={StaticResource IsNotNullBoolConverter}}" Command="{Binding OpenWikiCommand}" Margin="0,10,0,0" Style="{StaticResource Style_Button_Primary}"/>
<StackLayout Grid.Row="2" VerticalOptions="End" IsVisible="{Binding MachineItem.CanManage}" Margin="0,50,0,0">
<Label Text="{x:Static resource_text:TextResource.MachinePage_ManageMachine}" Style="{StaticResource Style_Label_Property_Title}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_ManageMachine}" Style="{StaticResource Style_Label_Property_Title}"/>
<StackLayout Margin="10, 0, 0, 20" Orientation="Horizontal" IsVisible="{Binding MachineItem.LastUser, Converter={StaticResource IsNotNullBoolConverter}}"> <StackLayout Orientation="Horizontal" IsVisible="{Binding MachineItem.LastUser, Converter={StaticResource IsNotNullBoolConverter}}">
<Label Text="{x:Static resource_text:TextResource.MachinePage_LastUser}" Style="{StaticResource Style_Label_Property_Title}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_LastUser}" Style="{StaticResource Style_Label_Property_Title}"/>
<Label Text="{Binding MachineItem.LastUser.Username}" Style="{StaticResource Style_Label_Property_Text}" Margin="10, 0, 0, 0"/> <Label Text="{Binding MachineItem.LastUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout> </StackLayout>
<Button Text="{x:Static resource_text:TextResource.MachinePage_ForceFree}" Command="{Binding ForceFreeMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_ForceFree}" Command="{Binding ForceFreeMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="{x:Static resource_text:TextResource.MachinePage_ForceBlock}" Command="{Binding ForceBlockMachineCommand}" Style="{StaticResource Style_Button_Admin}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_ForceBlock}" Command="{Binding ForceBlockMachineCommand}" Style="{StaticResource Style_Button_Admin}"/>

View File

@ -15,7 +15,7 @@
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand">
<Label Text="{x:Static resource_text:TextResource.ServerListPage_ActiveConnection}" IsVisible="{Binding HasActiveConnection}"/> <Label Text="{x:Static resource_text:TextResource.ServerListPage_ActiveConnection}" IsVisible="{Binding HasActiveConnection}"/>

View File

@ -13,7 +13,8 @@
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_TryConnection}" IsVisible="{Binding TestConnection}" Style="{StaticResource Style_Label_Text_Center}"/>
<ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<Grid IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand"> <Grid IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -23,8 +24,11 @@
<StackLayout Grid.Row="0"> <StackLayout Grid.Row="0">
<Label Text="{Binding DisplayAddress}" Style="{StaticResource LabelStyle_Title}"/> <Label Text="{Binding DisplayAddress}" Style="{StaticResource LabelStyle_Title}"/>
<Label Text="{Binding Connection_Item.Username}" Style="{StaticResource Style_Label_Text_Center}"/> <Label Text="{Binding Connection_Item.Username}" Style="{StaticResource Style_Label_Text_Center}"/>
<Button IsVisible="{Binding InstanceIsDefaultConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_SetDefault}" Margin="0,10,0,0" Command="{Binding SetDefaultCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button IsVisible="{Binding InstanceIsDefaultConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_SetDefault}" Margin="0,10,0,0" Command="{Binding SetDefaultCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Label IsVisible="{Binding InstanceIsDefaultConnection}" Text="{x:Static resource_text:TextResource.ServerPage_IsDefault}" Style="{StaticResource Style_Label_Text_Center}"/> <Label IsVisible="{Binding InstanceIsDefaultConnection}" Text="{x:Static resource_text:TextResource.ServerPage_IsDefault}" Style="{StaticResource Style_Label_Text_Center}" TextColor="{StaticResource FourthColor}"/>
<Label IsVisible="{Binding InstanceIsDefaultConnection,Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_DefaultText}" Style="{StaticResource Style_Label_Text_Center}" TextColor="{StaticResource FourthColor}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_Connect}" Margin="0,10,0,0" Command="{Binding ConnectCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button IsVisible="{Binding InstanceIsActiveConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_Connect}" Margin="0,10,0,0" Command="{Binding ConnectCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection}" Text="{x:Static resource_text:TextResource.ServerPage_Disconnect}" Margin="0,10,0,0" Command="{Binding DisconnectCommand}" Style="{StaticResource Style_Button_Admin}"/> <Button IsVisible="{Binding InstanceIsActiveConnection}" Text="{x:Static resource_text:TextResource.ServerPage_Disconnect}" Margin="0,10,0,0" Command="{Binding DisconnectCommand}" Style="{StaticResource Style_Button_Admin}"/>
</StackLayout> </StackLayout>

View File

@ -27,7 +27,7 @@
</MultiBinding> </MultiBinding>
</StackLayout.IsVisible> </StackLayout.IsVisible>
<Button Text="{x:Static resource_text:TextResource.UserListPage_AddUser}" Command="{Binding AddUserCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.UserListPage_AddUser}" Command="{Binding AddUserCommand}" Style="{StaticResource Style_Button_Primary}"/>
<SearchBar Text="{Binding SearchUsername}" SearchCommand="{Binding SearchUserCommand}"> <SearchBar Text="{Binding SearchUsername}" SearchCommand="{Binding SearchUserCommand}" Placeholder="{x:Static resource_text:TextResource.UserListPage_Search}" PlaceholderColor="{StaticResource SecondColor}">
<SearchBar.Behaviors> <SearchBar.Behaviors>
<prism:EventToCommandBehavior EventName="TextChanged" Command="{Binding SearchUserCommand}"/> <prism:EventToCommandBehavior EventName="TextChanged" Command="{Binding SearchUserCommand}"/>
</SearchBar.Behaviors> </SearchBar.Behaviors>

View File

@ -22,7 +22,7 @@
<StackLayout.IsVisible> <StackLayout.IsVisible>
<MultiBinding Converter="{StaticResource AllTrueBoolConverter}"> <MultiBinding Converter="{StaticResource AllTrueBoolConverter}">
<Binding Path="IsBusy" Converter="{StaticResource InvertBoolConverter}"/> <Binding Path="IsBusy" Converter="{StaticResource InvertBoolConverter}"/>
<Binding Path="IsConnected" /> <Binding Path="IsConnected"/>
</MultiBinding> </MultiBinding>
</StackLayout.IsVisible> </StackLayout.IsVisible>
<Label Text="{Binding UserItem.Username}" Style="{StaticResource LabelStyle_Title}"/> <Label Text="{Binding UserItem.Username}" Style="{StaticResource LabelStyle_Title}"/>
@ -40,7 +40,21 @@
<Entry Placeholder="{x:Static resource_text:TextResource.UserPage_NewPassword}" Text="{Binding NewPassword}"/> <Entry Placeholder="{x:Static resource_text:TextResource.UserPage_NewPassword}" Text="{Binding NewPassword}"/>
<Button Text="{x:Static resource_text:TextResource.UserPage_UpdatePassword}" Command="{Binding UpdatePasswordCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.UserPage_UpdatePassword}" Command="{Binding UpdatePasswordCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout> </StackLayout>
<Button Grid.Row="1" Text="{x:Static resource_text:TextResource.DELETE}" Command="{Binding DeleteCommand}" Style="{StaticResource Style_Button_Admin}" VerticalOptions="End"/> <StackLayout IsVisible="{Binding CanCreateCard}">
<StackLayout >
<StackLayout.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean">
<On Platform="iOS" Value="False" />
<On Platform="Android" Value="False" />
<On Platform="UWP" Value="True" />
</OnPlatform>
</StackLayout.IsVisible>
<Button Text="{x:Static resource_text:TextResource.UserPage_CreateCard}" Command="{Binding CreateCardCommand}" IsVisible="{Binding HasCardBinded, Converter={StaticResource InvertBoolConverter}}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="{x:Static resource_text:TextResource.UserPage_UnbindCard}" Command="{Binding UnbindCardCommand}" IsVisible="{Binding HasCardBinded}" Style="{StaticResource Style_Button_Admin}"/>
</StackLayout>
</StackLayout>
<Button Text="{x:Static resource_text:TextResource.DELETE}" Command="{Binding DeleteCommand}" Style="{StaticResource Style_Button_Admin}"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -71,6 +71,13 @@ namespace Borepin.PageModel.AddServerProcess
get => _Password; get => _Password;
set => SetProperty(ref _Password, value); set => SetProperty(ref _Password, value);
} }
private bool _TestConnection;
public bool TestConnection
{
get => _TestConnection;
set => SetProperty(ref _TestConnection, value);
}
#endregion #endregion
#region Commands #region Commands
@ -83,7 +90,8 @@ namespace Borepin.PageModel.AddServerProcess
public async Task AuthenticateCommandExecute() public async Task AuthenticateCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if(Username == null || Username == String.Empty || Password == null || Password == String.Empty) TestConnection = true;
if (Username == null || Username == String.Empty || Password == null || Password == String.Empty)
{ {
IsBusy = false; IsBusy = false;
return; return;
@ -103,23 +111,21 @@ namespace Borepin.PageModel.AddServerProcess
}, },
}; };
if (_API.IsConnected) try
{ {
if (_API.IsConnected) if (_API.IsConnecting || _API.IsConnected)
{ {
await _API.Disconnect().ConfigureAwait(true); await _API.Disconnect().ConfigureAwait(true);
_API.UnbindEventHandler(); _API.UnbindEventHandler();
} }
}
try
{
await _API.Connect(_ConnectionData).ConfigureAwait(false); await _API.Connect(_ConnectionData).ConfigureAwait(false);
} }
catch (Exception exception) catch (Exception exception)
{ {
_ErrorMessageService.DisplayConnectFailedMessage(exception); _ErrorMessageService.DisplayConnectFailedMessage(exception);
IsBusy = false; IsBusy = false;
TestConnection = false;
return; return;
} }
@ -134,6 +140,9 @@ namespace Borepin.PageModel.AddServerProcess
Log.Fatal(result.Exception, "Navigating failed"); Log.Fatal(result.Exception, "Navigating failed");
} }
}); });
IsBusy = false;
TestConnection = false;
} }
#endregion #endregion
} }

View File

@ -1,7 +1,6 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Service.ErrorMessage; using Borepin.Service.ErrorMessage;
using FabAccessAPI; using FabAccessAPI;
using FabAccessAPI.Exceptions;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
@ -28,6 +27,8 @@ namespace Borepin.PageModel.AddServerProcess
ConnectToServerCommand = new DelegateCommand(async () => await ConnectToServerExecute().ConfigureAwait(false)); ConnectToServerCommand = new DelegateCommand(async () => await ConnectToServerExecute().ConfigureAwait(false));
DetectLocalServerCommand = new DelegateCommand(DetectHostCommandExecute); DetectLocalServerCommand = new DelegateCommand(DetectHostCommandExecute);
ScanCodeCommand = new DelegateCommand(ScanCodeCommandExecute); ScanCodeCommand = new DelegateCommand(ScanCodeCommandExecute);
TestConnection = false;
} }
#endregion #endregion
@ -37,7 +38,7 @@ namespace Borepin.PageModel.AddServerProcess
if(instance is ConnectionData) if(instance is ConnectionData)
{ {
_ConnectionData = instance as ConnectionData; _ConnectionData = instance as ConnectionData;
Host = _ConnectionData.Host.ToString(); Host = _ConnectionData.Host.Host + ":" + _ConnectionData.Host.Port;
} }
return Task.CompletedTask; return Task.CompletedTask;
@ -66,6 +67,13 @@ namespace Borepin.PageModel.AddServerProcess
get => _Host; get => _Host;
set => SetProperty(ref _Host, value); set => SetProperty(ref _Host, value);
} }
private bool _TestConnection;
public bool TestConnection
{
get => _TestConnection;
set => SetProperty(ref _TestConnection, value);
}
#endregion #endregion
#region Commands #region Commands
@ -86,6 +94,7 @@ namespace Borepin.PageModel.AddServerProcess
try try
{ {
TestConnection = true;
string server_address = ""; string server_address = "";
if(Regex.IsMatch(Host, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1))) if(Regex.IsMatch(Host, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1)))
{ {
@ -101,6 +110,7 @@ namespace Borepin.PageModel.AddServerProcess
{ {
builder.Port = 59661; builder.Port = 59661;
} }
builder.Scheme = "fabaccess";
_ConnectionData = new ConnectionData() _ConnectionData = new ConnectionData()
{ {
@ -113,6 +123,7 @@ namespace Borepin.PageModel.AddServerProcess
{ {
await _PageDialogService.DisplayAlertAsync(Resources.Text.TextResource.ALERT_ConnectionFailed, Resources.Text.TextResource.ALERT_AddressInvalid, Resources.Text.TextResource.OK).ConfigureAwait(false); await _PageDialogService.DisplayAlertAsync(Resources.Text.TextResource.ALERT_ConnectionFailed, Resources.Text.TextResource.ALERT_AddressInvalid, Resources.Text.TextResource.OK).ConfigureAwait(false);
TestConnection = false;
IsBusy = false; IsBusy = false;
}); });
@ -127,6 +138,8 @@ namespace Borepin.PageModel.AddServerProcess
catch(Exception exception) catch(Exception exception)
{ {
_ErrorMessageService.DisplayConnectFailedMessage(exception); _ErrorMessageService.DisplayConnectFailedMessage(exception);
TestConnection = false;
IsBusy = false; IsBusy = false;
return; return;
} }
@ -139,6 +152,9 @@ namespace Borepin.PageModel.AddServerProcess
Log.Fatal(result.Exception, "Navigating failed"); Log.Fatal(result.Exception, "Navigating failed");
} }
}); });
TestConnection = false;
IsBusy = false;
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;

View File

@ -0,0 +1,441 @@
using Borepin.Base;
using Prism.Commands;
using Prism.Navigation;
using System.Windows.Input;
using FabAccessAPI.Schema;
using Prism.Services;
using Borepin.Service;
using System.Threading.Tasks;
using Borepin.Base.Exceptions;
using NFC.Interfaces;
using System.Collections.Generic;
using Borepin.Model;
using Xamarin.Forms;
using System;
using Borepin.Service.ErrorMessage;
using System.Linq;
namespace Borepin.PageModel
{
public class CreateCardPageModel : ConnectionModelBase
{
#region Private Fields
private CardConfig _CardConfig;
private User _User;
private INFCService _NFCService;
private IErrorMessageService _ErrorMessageService;
private KeyTypes _ScanKeyType = KeyTypes.NONE;
private KeyTypes _ScanedKeyType = KeyTypes.NONE;
#endregion
#region Contructors
public CreateCardPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, INFCService nfcService, IErrorMessageService errorMessageService) : base(navigationService, pageDialogService, apiService)
{
_NFCService = nfcService;
_ErrorMessageService = errorMessageService;
_CardConfig= new CardConfig();
CreateCardCommand = new DelegateCommand(CreateCardCommandExecute);
ScanPICCKeyCommand = new DelegateCommand(ScanPICCKeyCommandExecute);
ScanAPPKeyCommand = new DelegateCommand(ScanAPPKeyCommandExecute);
RandomAPPKeyCommand = new DelegateCommand(RandomAPPKeyCommandExecute);
RefreshCommand = new DelegateCommand(async () => await RefreshCommandExecute().ConfigureAwait(true));
}
#endregion
#region Data
public override Task LoadInstance(object instance)
{
if (instance is string)
{
_CardConfig.UserID = instance as string;
}
else if (instance is CardConfig)
{
_CardConfig = instance as CardConfig;
}
else if (instance is KeyScan)
{
KeyScan keyScan = instance as KeyScan;
_CardConfig = keyScan.CardConfig;
_ScanedKeyType = keyScan.KeyType;
_ScanKeyType = KeyTypes.NONE;
}
else
{
throw new InstanceIncorrectException();
}
return Task.CompletedTask;
}
public override Task LoadFromParameters(INavigationParameters parameters)
{
if (parameters.ContainsKey("result") && string.Equals((string)parameters["result"], "scanned", StringComparison.Ordinal) && parameters.ContainsKey("value"))
{
switch(_ScanedKeyType)
{
case (KeyTypes.PICC):
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
_CardConfig.PICCKey = _CardConfig.GenerateEmptyKey();
}
_CardConfig.PICCKey = _CardConfig.ConvertFromString((string)parameters["value"]);
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
break;
case (KeyTypes.APP):
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString((string)parameters["value"]);
}
catch
{
_CardConfig.APPKey = _CardConfig.GenerateEmptyKey();
}
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
break;
}
}
return Task.CompletedTask;
}
public override async Task LoadAPIData()
{
_User = (await _API.Session.UserSystem.Search.GetUserByName(_CardConfig.UserID).ConfigureAwait(false)).Just;
ReaderIDs = await Task.Run(() =>
{
return _NFCService.GetReaderIDs();
}).ConfigureAwait(false);
// Delay to sync with XAML Picker Item Source
await Task.Delay(100).ConfigureAwait(false);
if (ReaderIDs.Count > 0)
{
ReaderID = ReaderIDs[0];
}
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
FormatCard = _CardConfig.DoFormat;
}
public override Task<object> CreateInstance()
{
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
_CardConfig.PICCKey = _CardConfig.GenerateEmptyKey();
}
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString(APPKey);
}
catch
{
_CardConfig.APPKey = _CardConfig.GenerateEmptyKey();
}
_CardConfig.DoFormat = FormatCard;
switch(_ScanKeyType)
{
case (KeyTypes.PICC):
return Task.FromResult<object>(new KeyScan(_CardConfig, KeyTypes.PICC));
case (KeyTypes.APP):
return Task.FromResult<object>(new KeyScan(_CardConfig, KeyTypes.APP));
case (KeyTypes.NONE):
default:
return Task.FromResult<object>(_CardConfig);
}
}
#endregion
#region Fields
private IList<string> _ReaderIDs;
public IList<string> ReaderIDs
{
get => _ReaderIDs;
set => SetProperty(ref _ReaderIDs, value);
}
private string _ReaderID;
public string ReaderID
{
get => _ReaderID;
set => SetProperty(ref _ReaderID, value);
}
private string _PICCKey;
public string PICCKey
{
get => _PICCKey;
set => SetProperty(ref _PICCKey, value);
}
private string _APPKey;
public string APPKey
{
get => _APPKey;
set => SetProperty(ref _APPKey, value);
}
private bool _FormatCard;
public bool FormatCard
{
get => _FormatCard;
set => SetProperty(ref _FormatCard, value);
}
#endregion
#region Commands
private ICommand _RefreshCommand;
public ICommand RefreshCommand
{
get => _RefreshCommand;
set => SetProperty(ref _RefreshCommand, value);
}
public async Task RefreshCommandExecute()
{
if (_API.IsConnected)
{
try
{
await LoadAPIData().ConfigureAwait(true);
}
catch (System.Exception)
{
// TODO
}
}
}
private ICommand _CreateCardCommand;
public ICommand CreateCardCommand
{
get => _CreateCardCommand;
set => SetProperty(ref _CreateCardCommand, value);
}
public async void CreateCardCommandExecute()
{
IsBusy = true;
if(ReaderID == null)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "No Card Reader selected", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "PICC Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString(APPKey);
}
catch
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "APP Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
_CardConfig.DoFormat = FormatCard;
_CardConfig.CardToken = (await _User.CardDESFireEV2.GenCardToken().ConfigureAwait(false)).ToArray();
_CardConfig.SpaceInfo = (await _User.CardDESFireEV2.GetSpaceInfo().ConfigureAwait(false)).ToArray();
_CardConfig.MetaInfo = (await _User.CardDESFireEV2.GetMetaInfo().ConfigureAwait(false)).ToArray();
FabFireCard fabFireCard = new FabFireCard(_NFCService, _ErrorMessageService);
try
{
if(FormatCard)
{
fabFireCard.FormatCard(ReaderID, _CardConfig);
}
}
catch(Exception exception)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "Format failed", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
_NFCService.Disconnect();
return;
}
try
{
byte[] key = fabFireCard.CreateCard(ReaderID, _CardConfig);
await _User.CardDESFireEV2.Bind(_CardConfig.CardToken, new List<byte>(key)).ConfigureAwait(false);
}
catch(Exception excpetion)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "Card Creation failed", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
_NFCService.Disconnect();
return;
}
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.GoBackAsync().ConfigureAwait(false);
});
IsBusy = false;
}
#region PICCKey
private ICommand _ScanPICCKeyCommand;
public ICommand ScanPICCKeyCommand
{
get => _ScanPICCKeyCommand;
set => SetProperty(ref _ScanPICCKeyCommand, value);
}
public void ScanPICCKeyCommandExecute()
{
_ScanKeyType = KeyTypes.PICC;
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("ScanPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
private ICommand _RandomPICCKeyCommand;
public ICommand RandomPICCKeyCommand
{
get => _RandomPICCKeyCommand;
set => SetProperty(ref _RandomPICCKeyCommand, value);
}
public void RandomPICCKeyCommandExecute()
{
_CardConfig.PICCKey = _CardConfig.GenerateRandomKey();
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
}
private ICommand _ExportPICCKeyCommand;
public ICommand ExportPICCKeyCommand
{
get => _ExportPICCKeyCommand;
set => SetProperty(ref _ExportPICCKeyCommand, value);
}
public async void ExportPICCKeyCommandExecute()
{
IsBusy = true;
await Task.Delay(1000).ConfigureAwait(false);
IsBusy = false;
}
#endregion
#region APPKey
private ICommand _ScanAPPKeyCommand;
public ICommand ScanAPPKeyCommand
{
get => _ScanAPPKeyCommand;
set => SetProperty(ref _ScanAPPKeyCommand, value);
}
public void ScanAPPKeyCommandExecute()
{
_ScanKeyType = KeyTypes.APP;
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("ScanPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
private ICommand _RandomAPPKeyCommand;
public ICommand RandomAPPKeyCommand
{
get => _RandomAPPKeyCommand;
set => SetProperty(ref _RandomAPPKeyCommand, value);
}
public void RandomAPPKeyCommandExecute()
{
_CardConfig.APPKey = _CardConfig.GenerateRandomKey();
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
}
private ICommand _ExportAPPKeyCommand;
public ICommand ExportAPPKeyCommand
{
get => _ExportAPPKeyCommand;
set => SetProperty(ref _ExportAPPKeyCommand, value);
}
public async void ExportAPPKeyCommandExecute()
{
IsBusy = true;
await Task.Delay(1000).ConfigureAwait(false);
IsBusy = false;
}
#endregion
#endregion
}
}

View File

@ -11,6 +11,7 @@ using Borepin.Base.Exceptions;
using Capnp.Rpc; using Capnp.Rpc;
using System; using System;
using Borepin.Service.Browser; using Borepin.Service.Browser;
using System.Text;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -33,6 +34,9 @@ namespace Borepin.PageModel
ForceBlockMachineCommand = new DelegateCommand(ForceBlockMachineCommandExecute); ForceBlockMachineCommand = new DelegateCommand(ForceBlockMachineCommandExecute);
ForceDisableMachineCommand = new DelegateCommand(ForceDisableMachineCommandExecute); ForceDisableMachineCommand = new DelegateCommand(ForceDisableMachineCommandExecute);
OpenWikiCommand = new DelegateCommand(OpenWikiCommandExecute); OpenWikiCommand = new DelegateCommand(OpenWikiCommandExecute);
UnlockLockCommand = new DelegateCommand(UnlockLockCommandExecute);
IdentifyLockCommand = new DelegateCommand(IdentifyLockCommandExecute);
} }
#endregion #endregion
@ -236,6 +240,52 @@ namespace Borepin.PageModel
} }
} }
} }
private ICommand _UnlockLockCommand;
public ICommand UnlockLockCommand
{
get => _UnlockLockCommand;
set => SetProperty(ref _UnlockLockCommand, value);
}
public async void UnlockLockCommandExecute()
{
if (_API.IsConnected)
{
try
{
Machine.IProdInterface prodInterface = _Machine.Prodable;
await prodInterface.ProdWithData(Encoding.ASCII.GetBytes("action: unlock")).ConfigureAwait(false);
}
catch (RpcException exception) when (string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
}
}
private ICommand _IdentifyLockCommand;
public ICommand IdentifyLockCommand
{
get => _IdentifyLockCommand;
set => SetProperty(ref _IdentifyLockCommand, value);
}
public async void IdentifyLockCommandExecute()
{
if (_API.IsConnected)
{
try
{
Machine.IProdInterface prodInterface = _Machine.Prodable;
await prodInterface.ProdWithData(Encoding.ASCII.GetBytes("action: identify")).ConfigureAwait(false);
}
catch (RpcException exception) when (string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
}
}
#endregion #endregion
} }
} }

View File

@ -112,6 +112,13 @@ namespace Borepin.PageModel
get => _InstanceIsDefaultConnection; get => _InstanceIsDefaultConnection;
set => SetProperty(ref _InstanceIsDefaultConnection, value); set => SetProperty(ref _InstanceIsDefaultConnection, value);
} }
private bool _TestConnection;
public bool TestConnection
{
get => _TestConnection;
set => SetProperty(ref _TestConnection, value);
}
#endregion #endregion
#region Commands #region Commands
@ -124,19 +131,23 @@ namespace Borepin.PageModel
public async Task ConnectCommandExecute() public async Task ConnectCommandExecute()
{ {
IsBusy = true; IsBusy = true;
TestConnection = true;
if(_API.IsConnected)
{
await _API.Disconnect().ConfigureAwait(true);
}
try try
{ {
if (_API.IsConnecting || _API.IsConnected)
{
await _API.Disconnect().ConfigureAwait(true);
_API.UnbindEventHandler();
}
await _API.Connect(Connection_Item).ConfigureAwait(false); await _API.Connect(Connection_Item).ConfigureAwait(false);
} }
catch(Exception exception) catch(Exception exception)
{ {
_ErrorMessageService.DisplayConnectFailedMessage(exception); _ErrorMessageService.DisplayConnectFailedMessage(exception);
TestConnection = false;
IsBusy = false; IsBusy = false;
return; return;
} }
@ -151,6 +162,9 @@ namespace Borepin.PageModel
Log.Fatal(result.Exception, "Navigating failed"); Log.Fatal(result.Exception, "Navigating failed");
} }
}); });
TestConnection = false;
IsBusy = false;
} }
private ICommand _SetDefaultCommand; private ICommand _SetDefaultCommand;
public ICommand SetDefaultCommand public ICommand SetDefaultCommand

View File

@ -16,6 +16,7 @@ using NaturalSort.Extension;
using System.Linq; using System.Linq;
using Prism.Services.Dialogs; using Prism.Services.Dialogs;
using Xamarin.Forms; using Xamarin.Forms;
using ZXing;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -34,6 +35,8 @@ namespace Borepin.PageModel
_DialogService = dialogService; _DialogService = dialogService;
DeleteCommand = new DelegateCommand(DeleteCommandExecute); DeleteCommand = new DelegateCommand(DeleteCommandExecute);
UpdatePasswordCommand = new DelegateCommand(UpdatePasswordCommandExecute); UpdatePasswordCommand = new DelegateCommand(UpdatePasswordCommandExecute);
CreateCardCommand = new DelegateCommand(CreateCardCommandExecute);
UnbindCardCommand = new DelegateCommand(UnbindCardCommandExecute);
} }
#endregion #endregion
@ -44,6 +47,10 @@ namespace Borepin.PageModel
{ {
_ID = instance as string; _ID = instance as string;
} }
else if (instance is CardConfig)
{
_ID = (instance as CardConfig).UserID;
}
else if(instance == null && _IsDialog) else if(instance == null && _IsDialog)
{ {
@ -64,6 +71,11 @@ namespace Borepin.PageModel
} }
_User = (await _API.Session.UserSystem.Search.GetUserByName(_ID).ConfigureAwait(false)).Just; _User = (await _API.Session.UserSystem.Search.GetUserByName(_ID).ConfigureAwait(false)).Just;
if(_User == null )
{
return;
}
UserItem = new UserVisualize(_User); UserItem = new UserVisualize(_User);
await UserItem.LoadData().ConfigureAwait(false); await UserItem.LoadData().ConfigureAwait(false);
@ -89,6 +101,13 @@ namespace Borepin.PageModel
CanAdmin = !((UserSystem.ManageInterface_Proxy)_API.Session.UserSystem.Manage).IsNull; CanAdmin = !((UserSystem.ManageInterface_Proxy)_API.Session.UserSystem.Manage).IsNull;
CanManage = !((User.ManageInterface_Proxy)_User.Manage).IsNull; CanManage = !((User.ManageInterface_Proxy)_User.Manage).IsNull;
CanCreateCard = !((User.CardDESFireInterface_Proxy)_User.CardDESFireEV2).IsNull;
if(CanCreateCard)
{
IReadOnlyList<IReadOnlyList<byte>> list = await _User.CardDESFireEV2.GetTokenList().ConfigureAwait(false);
HasCardBinded = list != null && list.Count > 0;
}
} }
#endregion #endregion
@ -121,6 +140,20 @@ namespace Borepin.PageModel
set => SetProperty(ref _CanManage, value); set => SetProperty(ref _CanManage, value);
} }
private bool _CanCreateCard;
public bool CanCreateCard
{
get => _CanCreateCard;
set => SetProperty(ref _CanCreateCard, value);
}
private bool _HasCardBinded;
public bool HasCardBinded
{
get => _HasCardBinded;
set => SetProperty(ref _HasCardBinded, value);
}
private string _NewPassword; private string _NewPassword;
public string NewPassword public string NewPassword
{ {
@ -208,6 +241,60 @@ namespace Borepin.PageModel
} }
IsBusy = false; IsBusy = false;
} }
private ICommand _UnbindCardCommand;
public ICommand UnbindCardCommand
{
get => _UnbindCardCommand;
set => SetProperty(ref _UnbindCardCommand, value);
}
public async void UnbindCardCommandExecute()
{
IsBusy = true;
IReadOnlyList<IReadOnlyList<byte>> list = await _User.CardDESFireEV2.GetTokenList().ConfigureAwait(false);
if(list.Count > 0)
{
await _User.CardDESFireEV2.Unbind(list[0]).ConfigureAwait(false);
try
{
await LoadAPIData().ConfigureAwait(false);
}
catch
{
// TODO
}
}
IsBusy = false;
}
private ICommand _CreateCardCommand;
public ICommand CreateCardCommand
{
get => _CreateCardCommand;
set => SetProperty(ref _CreateCardCommand, value);
}
public void CreateCardCommandExecute()
{
IsBusy = true;
NavigationParameters parameters = new NavigationParameters
{
{ "instance", _ID },
};
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result_nav = await _NavigationService.NavigateAsync("CreateCardPage", parameters).ConfigureAwait(false);
if (result_nav.Exception != null)
{
Log.Fatal(result_nav.Exception, "Navigating failed");
}
});
IsBusy = false;
}
#endregion #endregion
} }
} }

View File

@ -124,9 +124,9 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die FabAccess is a decentralized machine management system. Each Space thus uses its own server. /// Sucht eine lokalisierte Zeichenfolge, die FabAccess is a decentralized machine management system, which means that it is designed to allow each Space to have its own dedicated server for managing its machines. If you want to connect to the FabAccess server for a specific Space, you will need to obtain the host address from that particular Space.
///Ask your Space for the address of your server. ///
///You can also put down several servers and then connect to the desired server. ähnelt. ///In addition to being able to connect to individual servers, FabAccess also allows you to add multiple servers to your account. This feature is especially useful for makers and innovators who have access [Rest der Zeichenfolge wurde abgeschnitten]&quot;; ähnelt.
/// </summary> /// </summary>
internal static string AddServerProcess_SelectServerPage_Info { internal static string AddServerProcess_SelectServerPage_Info {
get { get {
@ -134,6 +134,24 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die test.fab-access.org ähnelt.
/// </summary>
internal static string AddServerProcess_SelectServerPage_Placeholder {
get {
return ResourceManager.GetString("AddServerProcess_SelectServerPage_Placeholder", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Trying to connect to the server ähnelt.
/// </summary>
internal static string AddServerProcess_SelectServerPage_TryConnection {
get {
return ResourceManager.GetString("AddServerProcess_SelectServerPage_TryConnection", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Add User ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Add User ähnelt.
/// </summary> /// </summary>
@ -162,7 +180,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Add User failed ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Add User failed. ähnelt.
/// </summary> /// </summary>
internal static string ALERT_AddUserFailed { internal static string ALERT_AddUserFailed {
get { get {
@ -171,7 +189,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Authentication failed ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Authentication failed. ähnelt.
/// </summary> /// </summary>
internal static string ALERT_AuthFailed { internal static string ALERT_AuthFailed {
get { get {
@ -189,7 +207,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die SASL Mechanism is not supported- ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die SASL Mechanism is not supported. ähnelt.
/// </summary> /// </summary>
internal static string ALERT_BadMechanism { internal static string ALERT_BadMechanism {
get { get {
@ -198,7 +216,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Connection failed ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Connection failed. ähnelt.
/// </summary> /// </summary>
internal static string ALERT_ConnectionFailed { internal static string ALERT_ConnectionFailed {
get { get {
@ -233,6 +251,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ID is invalid. ähnelt.
/// </summary>
internal static string ALERT_ID {
get {
return ResourceManager.GetString("ALERT_ID", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Password is invalid. ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Password is invalid. ähnelt.
/// </summary> /// </summary>
@ -252,7 +279,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die SASL Authenticaiton failed ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die SASL Authentication failed ähnelt.
/// </summary> /// </summary>
internal static string ALERT_SASLAuth { internal static string ALERT_SASLAuth {
get { get {
@ -288,7 +315,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die User allready exist. ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die User already exist. ähnelt.
/// </summary> /// </summary>
internal static string ALERT_UserExist { internal static string ALERT_UserExist {
get { get {
@ -306,7 +333,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die It&apos;s Bionade ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die It&apos;s Bionade! ähnelt.
/// </summary> /// </summary>
internal static string Bionade { internal static string Bionade {
get { get {
@ -342,7 +369,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Connecting to Server ... ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Connecting to Server ähnelt.
/// </summary> /// </summary>
internal static string ConnectionStatus_Connecting { internal static string ConnectionStatus_Connecting {
get { get {
@ -387,7 +414,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die &quot;Do you really want to delete this Server?&quot; ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Do you really want to delete this Server? ähnelt.
/// </summary> /// </summary>
internal static string DIALOG_DeleteServerConfirm { internal static string DIALOG_DeleteServerConfirm {
get { get {
@ -450,8 +477,8 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die You do not have the authorization to use this machine. /// Sucht eine lokalisierte Zeichenfolge, die You are not currently authorized to use this machine.
///Ask in your Space if you can be trained on the machine to be unlocked for the machine. ähnelt. ///Please speak with the staff at the Space to receive the necessary training and authorization. ähnelt.
/// </summary> /// </summary>
internal static string MachinePage_CanNotUseByPermission { internal static string MachinePage_CanNotUseByPermission {
get { get {
@ -504,6 +531,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Identify ähnelt.
/// </summary>
internal static string MachinePage_Identify {
get {
return ResourceManager.GetString("MachinePage_Identify", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Last User: ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Last User: ähnelt.
/// </summary> /// </summary>
@ -711,6 +747,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die You can set a server as the default server and then the app will automatically connect to that server upon startup. ähnelt.
/// </summary>
internal static string ServerPage_DefaultText {
get {
return ResourceManager.GetString("ServerPage_DefaultText", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Disconnect ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Disconnect ähnelt.
/// </summary> /// </summary>
@ -721,7 +766,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Is Default Connection ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die This connection has been set as the default and FabAccess will automatically connect to this server upon startup. ähnelt.
/// </summary> /// </summary>
internal static string ServerPage_IsDefault { internal static string ServerPage_IsDefault {
get { get {
@ -766,7 +811,9 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Automate your Space with FabAccess ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die FabAccess is a machine management system designed for makerspaces, fablab and other collaborative workspaces.
///
///With FabAccess, you can access and schedule machines, manage users and receive real-time updates on machine status and usage. The platform provides a decentralized solution for managing and connecting to machines across different Spaces, making it easier for users to collaborate and innovate together. ähnelt.
/// </summary> /// </summary>
internal static string SetUpProcess_WelcomePage_Text { internal static string SetUpProcess_WelcomePage_Text {
get { get {
@ -775,7 +822,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Welcome ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Welcome to FabAccess ähnelt.
/// </summary> /// </summary>
internal static string SetUpProcess_WelcomePage_Title { internal static string SetUpProcess_WelcomePage_Title {
get { get {
@ -901,7 +948,7 @@ namespace Borepin.Resources.Text {
} }
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Add User ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Add new User ähnelt.
/// </summary> /// </summary>
internal static string UserListPage_AddUser { internal static string UserListPage_AddUser {
get { get {
@ -909,6 +956,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Search User ähnelt.
/// </summary>
internal static string UserListPage_Search {
get {
return ResourceManager.GetString("UserListPage_Search", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Search Username ... ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Search Username ... ähnelt.
/// </summary> /// </summary>
@ -936,6 +992,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Create new FabFire Card ähnelt.
/// </summary>
internal static string UserPage_CreateCard {
get {
return ResourceManager.GetString("UserPage_CreateCard", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die New Password ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die New Password ähnelt.
/// </summary> /// </summary>
@ -945,6 +1010,15 @@ namespace Borepin.Resources.Text {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Unbind FabFire Card ähnelt.
/// </summary>
internal static string UserPage_UnbindCard {
get {
return ResourceManager.GetString("UserPage_UnbindCard", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Force Password Update ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Force Password Update ähnelt.
/// </summary> /// </summary>

View File

@ -0,0 +1,452 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddServerProcess_AuthPlainPage_Login" xml:space="preserve">
<value>Login</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginCard" xml:space="preserve">
<value>Login mit Karte</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginPassword" xml:space="preserve">
<value>Login mit Passwort</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_Register" xml:space="preserve">
<value>Registrieren</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignIn" xml:space="preserve">
<value>Eintragen:</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignUp" xml:space="preserve">
<value>Anmelden:</value>
</data>
<data name="AddServerProcess_SelectServerPage_Connect" xml:space="preserve">
<value>Zu Server verbinden</value>
</data>
<data name="AddServerProcess_SelectServerPage_Info" xml:space="preserve">
<value>FabAccess ist ein dezentralisiertes Maschinenverwaltungssystem, d.h. es ist so konzipiert, dass jeder Space seinen eigenen dedizierten Server für die Verwaltung seiner Maschinen hat. Wenn Sie sich mit dem FabAccess-Server eines bestimmten Spaces verbinden wollen, müssen Sie die Host-Adresse von diesem Space erhalten.
Neben der Möglichkeit, sich mit einzelnen Servern zu verbinden, können Sie mit FabAccess auch mehrere Server zu Ihrem Konto hinzufügen. Diese Funktion ist besonders nützlich für Macher und Innovatoren, die Zugang zu Maschinen in mehreren Spaces haben.</value>
</data>
<data name="AddServerProcess_SelectServerPage_Placeholder" xml:space="preserve">
<value>test.fab-access.org</value>
</data>
<data name="AddServerProcess_SelectServerPage_TryConnection" xml:space="preserve">
<value>Versuche Verbindung zu Server</value>
</data>
<data name="AddUserPage_AddUser" xml:space="preserve">
<value>Benutzer hinzufügen</value>
</data>
<data name="ALERT" xml:space="preserve">
<value>Warnung</value>
</data>
<data name="ALERT_AddressInvalid" xml:space="preserve">
<value>Server-Adresse ist ungültig.</value>
</data>
<data name="ALERT_AddUserFailed" xml:space="preserve">
<value>Benutzer hinzufügen fehlgeschlagen.</value>
</data>
<data name="ALERT_AuthFailed" xml:space="preserve">
<value>Authentifizierung fehlgeschlagen.</value>
</data>
<data name="ALERT_AuthServer" xml:space="preserve">
<value>Authentifizierung beim Server nicht möglich.</value>
</data>
<data name="ALERT_BadMechanism" xml:space="preserve">
<value>SASL Mechanismus nicht unterstützt.</value>
</data>
<data name="ALERT_ConnectionFailed" xml:space="preserve">
<value>Verbindung fehlgeschlagen.</value>
</data>
<data name="ALERT_ConnectionTimeout" xml:space="preserve">
<value>Verbindungszeit überschritten.</value>
</data>
<data name="ALERT_CredentialsInvalid" xml:space="preserve">
<value>Anmeldeinformationen ungültig.</value>
</data>
<data name="ALERT_DuplicateConnection" xml:space="preserve">
<value>Verbindung existiert bereits. Bitte alte Verbindung löschen, bevor neue Verbindung hinzugefügt wird.</value>
</data>
<data name="ALERT_ID" xml:space="preserve">
<value>ID ist ungültig.</value>
</data>
<data name="ALERT_PasswordInvalid" xml:space="preserve">
<value>Passwort ist ungültig.</value>
</data>
<data name="ALERT_QRInvalid" xml:space="preserve">
<value>QR Code inst ungültig</value>
</data>
<data name="ALERT_SASLAuth" xml:space="preserve">
<value>SASLAuthentifizierung fehlgeschlagen</value>
</data>
<data name="ALERT_TLSInvalid" xml:space="preserve">
<value>TLS-Zertifikat ist ungültig.</value>
</data>
<data name="ALERT_UnableServer" xml:space="preserve">
<value>Verbindung zum Server kann nicht hergestellt werden.</value>
</data>
<data name="ALERT_UnexpectedError" xml:space="preserve">
<value>Unerwarteter Fehler.</value>
</data>
<data name="ALERT_UserExist" xml:space="preserve">
<value>Benutzer existiert bereits.</value>
</data>
<data name="ALERT_UsernameInvalid" xml:space="preserve">
<value>Benutzername ungültig.</value>
</data>
<data name="Bionade" xml:space="preserve">
<value>Es ist Bionade!</value>
</data>
<data name="BUILD" xml:space="preserve">
<value>Build</value>
</data>
<data name="CANCEL" xml:space="preserve">
<value>Abbrechen</value>
</data>
<data name="CONFIRM" xml:space="preserve">
<value>Bestätigen</value>
</data>
<data name="ConnectionStatus_Connecting" xml:space="preserve">
<value>Verbinde zu Server</value>
</data>
<data name="ConnectionStatus_NoConnection" xml:space="preserve">
<value>Keine Verbindung zu Server</value>
</data>
<data name="ConnectionStatus_NotConnected" xml:space="preserve">
<value>Bitte Server auswählen.</value>
</data>
<data name="DELETE" xml:space="preserve">
<value>Löschen</value>
</data>
<data name="DIALOG_DeleteServer" xml:space="preserve">
<value>Server löschen</value>
</data>
<data name="DIALOG_DeleteServerConfirm" xml:space="preserve">
<value>Wollen Sie diesen Server wirklich löschen?</value>
</data>
<data name="DIALOG_DeleteUser" xml:space="preserve">
<value>Benutzer löschen</value>
</data>
<data name="DIALOG_DeleteUserConfirm" xml:space="preserve">
<value>Wollen Sie diesen Benutzer wirklich löschen?</value>
</data>
<data name="FABACCESS" xml:space="preserve">
<value>FabAccess</value>
</data>
<data name="HOST" xml:space="preserve">
<value>Host</value>
</data>
<data name="InUseByMe" xml:space="preserve">
<value>Durch mich genutzt</value>
</data>
<data name="MACHINE" xml:space="preserve">
<value>Maschine</value>
</data>
<data name="MachinePage_CanNotUseByPermission" xml:space="preserve">
<value>Sie sind derzeit nicht berechtigt, dieses Gerät zu benutzen.
Bitte sprechen Sie mit dem Personal im Space, um die erforderliche Schulung und Genehmigung zu erhalten.</value>
</data>
<data name="MachinePage_CurrentUser" xml:space="preserve">
<value>Aktueller Benutzer:</value>
</data>
<data name="MachinePage_ForceBlock" xml:space="preserve">
<value>Maschine blockieren</value>
</data>
<data name="MachinePage_ForceDisable" xml:space="preserve">
<value>Maschine deaktivieren</value>
</data>
<data name="MachinePage_ForceFree" xml:space="preserve">
<value>Maschine freigeben</value>
</data>
<data name="MachinePage_GiveBack" xml:space="preserve">
<value>Maschine zurückgeben</value>
</data>
<data name="MachinePage_Identify" xml:space="preserve">
<value>Lokalisieren</value>
</data>
<data name="MachinePage_LastUser" xml:space="preserve">
<value>Letzter Benutzer:</value>
</data>
<data name="MachinePage_ManageMachine" xml:space="preserve">
<value>Maschine verwalten:</value>
</data>
<data name="MachinePage_OpenWiki" xml:space="preserve">
<value>Wiki öffnen</value>
</data>
<data name="MachinePage_Unlock" xml:space="preserve">
<value>Entsperren</value>
</data>
<data name="MachinePage_Use" xml:space="preserve">
<value>Benutzen</value>
</data>
<data name="MainPage_Build" xml:space="preserve">
<value>Build</value>
</data>
<data name="MainPage_Machines" xml:space="preserve">
<value>Maschinen</value>
</data>
<data name="MainPage_Profile" xml:space="preserve">
<value>Mein Profil</value>
</data>
<data name="MainPage_Servers" xml:space="preserve">
<value>Server</value>
</data>
<data name="MainPage_Users" xml:space="preserve">
<value>Benutzer</value>
</data>
<data name="MainPage_Version" xml:space="preserve">
<value>Version</value>
</data>
<data name="OK" xml:space="preserve">
<value>Ok</value>
</data>
<data name="OR" xml:space="preserve">
<value>oder</value>
</data>
<data name="PASSWORD" xml:space="preserve">
<value>Passwort</value>
</data>
<data name="ProfilePage_ChangePassword" xml:space="preserve">
<value>Passwort ändern</value>
</data>
<data name="ProfilePage_NewPassword" xml:space="preserve">
<value>Neues Passwort</value>
</data>
<data name="ProfilePage_OldPassword" xml:space="preserve">
<value>Altes Passwort</value>
</data>
<data name="ProfilePage_UpdatePassword" xml:space="preserve">
<value>Passwort aktualisieren</value>
</data>
<data name="SCANQR" xml:space="preserve">
<value>QR-Code scannen</value>
</data>
<data name="ServerListPage_ActiveConnection" xml:space="preserve">
<value>Aktive Verbindung</value>
</data>
<data name="ServerListPage_ConnectToNewServer" xml:space="preserve">
<value>Zu neuem Server verbinden</value>
</data>
<data name="ServerListPage_LastConnection" xml:space="preserve">
<value>Letzte Verbindungen</value>
</data>
<data name="ServerPageModel_ConnectionFailed" xml:space="preserve">
<value>Verbindung fehlgeschlagen</value>
</data>
<data name="ServerPage_Connect" xml:space="preserve">
<value>Verbinden</value>
</data>
<data name="ServerPage_DefaultText" xml:space="preserve">
<value>Sie können einen Server als Standardserver festlegen, so dass die Anwendung beim Start automatisch eine Verbindung zu diesem Server herstellt.</value>
</data>
<data name="ServerPage_Disconnect" xml:space="preserve">
<value>Verbindung trennen</value>
</data>
<data name="ServerPage_IsDefault" xml:space="preserve">
<value>Diese Verbindung ist als Standard eingestellt, und FabAccess verbindet sich beim Starten automatisch mit diesem Server.</value>
</data>
<data name="ServerPage_SetDefault" xml:space="preserve">
<value>Als Standardverbindung setzen</value>
</data>
<data name="SetUpProcess_ScanPage_Button" xml:space="preserve">
<value>In Space einloggen</value>
</data>
<data name="SetUpProcess_WelcomePage_Button" xml:space="preserve">
<value>Mit der Arbeit beginnen</value>
</data>
<data name="SetUpProcess_WelcomePage_Text" xml:space="preserve">
<value>FabAccess ist ein Maschinenverwaltungssystem, das für Makerspaces, Fablabs und andere kollaborative Arbeitsbereiche entwickelt wurde.
Mit FabAccess können Sie auf Maschinen zugreifen und diese planen, Benutzer verwalten und Echtzeit-Updates zu Maschinenstatus und -nutzung erhalten. Die Plattform bietet eine dezentralisierte Lösung für die Verwaltung von und den Zugriff auf Maschinen in verschiedenen Spaces und erleichtert den Nutzern die Zusammenarbeit und gemeinsame Innovation.</value>
</data>
<data name="SetUpProcess_WelcomePage_Title" xml:space="preserve">
<value>Willkommen bei FabAccess</value>
</data>
<data name="StartPage_Connecting" xml:space="preserve">
<value>Verbinde zu Server</value>
</data>
<data name="StartPage_Starting" xml:space="preserve">
<value>Anwendung wird gestartet</value>
</data>
<data name="TITLE_AddUser" xml:space="preserve">
<value>Benutzer hinzufügen</value>
</data>
<data name="TITLE_ConnectToServer" xml:space="preserve">
<value>Mit Server verbinden</value>
</data>
<data name="TITLE_Machine" xml:space="preserve">
<value>Maschine</value>
</data>
<data name="TITLE_Machines" xml:space="preserve">
<value>Maschinen</value>
</data>
<data name="TITLE_Profile" xml:space="preserve">
<value>Mein Profil</value>
</data>
<data name="TITLE_Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="TITLE_Servers" xml:space="preserve">
<value>Server</value>
</data>
<data name="TITLE_Settings" xml:space="preserve">
<value>Einstellungen</value>
</data>
<data name="TITLE_User" xml:space="preserve">
<value>Benutzer</value>
</data>
<data name="TITLE_Users" xml:space="preserve">
<value>Benutzer</value>
</data>
<data name="Uncategorised" xml:space="preserve">
<value>Unkategorisiert</value>
</data>
<data name="UserListPage_AddUser" xml:space="preserve">
<value>Neuen Benutzer hinzufügen</value>
</data>
<data name="UserListPage_Search" xml:space="preserve">
<value>Benutzer suchen</value>
</data>
<data name="UserListPage_SearchUser" xml:space="preserve">
<value>Benutzername suchen ...</value>
</data>
<data name="USERNAME" xml:space="preserve">
<value>Benutzername</value>
</data>
<data name="UserPage_ChangePassword" xml:space="preserve">
<value>Passwort aktualisieren</value>
</data>
<data name="UserPage_CreateCard" xml:space="preserve">
<value>Neue FabFire Card erzeugen</value>
</data>
<data name="UserPage_NewPassword" xml:space="preserve">
<value>Neues Passwort</value>
</data>
<data name="UserPage_UnbindCard" xml:space="preserve">
<value>FabFir eCard entkoppeln</value>
</data>
<data name="UserPage_UpdatePassword" xml:space="preserve">
<value>Passwort Update erzwingen</value>
</data>
<data name="VERSION" xml:space="preserve">
<value>Version</value>
</data>
<data name="YAY" xml:space="preserve">
<value>YAY</value>
</data>
</root>

View File

@ -0,0 +1,469 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddServerProcess_AuthPlainPage_Login" xml:space="preserve">
<value>Login</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginCard" xml:space="preserve">
<value>Login with Card</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginPassword" xml:space="preserve">
<value>Login with Password</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_Register" xml:space="preserve">
<value>Register</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignIn" xml:space="preserve">
<value>Sign In:</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignUp" xml:space="preserve">
<value>Sign Up:</value>
</data>
<data name="AddServerProcess_SelectServerPage_Connect" xml:space="preserve">
<value>Connect to Server</value>
</data>
<data name="AddServerProcess_SelectServerPage_Info" xml:space="preserve">
<value>FabAccess is a decentralized machine management system, which means that it is designed to allow each Space to have its own dedicated server for managing its machines. If you want to connect to the FabAccess server for a specific Space, you will need to obtain the host address from that particular Space.
In addition to being able to connect to individual servers, FabAccess also allows you to add multiple servers to your account. This feature is especially useful for makers and innovators who have access to machines at multiple Spaces.</value>
</data>
<data name="AddServerProcess_SelectServerPage_Placeholder" xml:space="preserve">
<value>test.fab-access.org</value>
</data>
<data name="AddServerProcess_SelectServerPage_TryConnection" xml:space="preserve">
<value>Trying to connect to the server</value>
</data>
<data name="AddUserPage_AddUser" xml:space="preserve">
<value>Add User</value>
</data>
<data name="ALERT" xml:space="preserve">
<value>Alert</value>
</data>
<data name="ALERT_AddressInvalid" xml:space="preserve">
<value>Server address is invaild.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_AddUserFailed" xml:space="preserve">
<value>Add User failed.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_AuthFailed" xml:space="preserve">
<value>Authentication failed.</value>
<comment>Message Title</comment>
</data>
<data name="ALERT_AuthServer" xml:space="preserve">
<value>Unable to authenticate to server.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_BadMechanism" xml:space="preserve">
<value>SASL Mechanism is not supported.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_ConnectionFailed" xml:space="preserve">
<value>Connection failed.</value>
<comment>Message Title</comment>
</data>
<data name="ALERT_ConnectionTimeout" xml:space="preserve">
<value>Connection time exceeded.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_CredentialsInvalid" xml:space="preserve">
<value>Credentials are invalid.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_DuplicateConnection" xml:space="preserve">
<value>Connection already exist. Please delete old Connection before adding the new Connection.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_ID" xml:space="preserve">
<value>ID is invalid.</value>
</data>
<data name="ALERT_PasswordInvalid" xml:space="preserve">
<value>Password is invalid.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_QRInvalid" xml:space="preserve">
<value>QR Code is invalid</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_SASLAuth" xml:space="preserve">
<value>SASL Authentication failed</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_TLSInvalid" xml:space="preserve">
<value>TLS certificate is invalid.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_UnableServer" xml:space="preserve">
<value>Unable to connect to server.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_UnexpectedError" xml:space="preserve">
<value>Unexpected Error.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_UserExist" xml:space="preserve">
<value>User already exist.</value>
<comment>Message Content</comment>
</data>
<data name="ALERT_UsernameInvalid" xml:space="preserve">
<value>Username is invalid.</value>
<comment>Message Content</comment>
</data>
<data name="Bionade" xml:space="preserve">
<value>It's Bionade!</value>
</data>
<data name="BUILD" xml:space="preserve">
<value>Build</value>
</data>
<data name="CANCEL" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="CONFIRM" xml:space="preserve">
<value>Confirm</value>
</data>
<data name="ConnectionStatus_Connecting" xml:space="preserve">
<value>Connecting to Server</value>
</data>
<data name="ConnectionStatus_NoConnection" xml:space="preserve">
<value>No Connection to Server</value>
</data>
<data name="ConnectionStatus_NotConnected" xml:space="preserve">
<value>Please select a Server.</value>
</data>
<data name="DELETE" xml:space="preserve">
<value>Delete</value>
</data>
<data name="DIALOG_DeleteServer" xml:space="preserve">
<value>Delete Server</value>
</data>
<data name="DIALOG_DeleteServerConfirm" xml:space="preserve">
<value>Do you really want to delete this Server?</value>
</data>
<data name="DIALOG_DeleteUser" xml:space="preserve">
<value>Delete User</value>
</data>
<data name="DIALOG_DeleteUserConfirm" xml:space="preserve">
<value>Do you really want to delete this User?</value>
</data>
<data name="FABACCESS" xml:space="preserve">
<value>FabAccess</value>
</data>
<data name="HOST" xml:space="preserve">
<value>Host</value>
</data>
<data name="InUseByMe" xml:space="preserve">
<value>In Use By Me</value>
</data>
<data name="MACHINE" xml:space="preserve">
<value>Machine</value>
</data>
<data name="MachinePage_CanNotUseByPermission" xml:space="preserve">
<value>You are not currently authorized to use this machine.
Please speak with the staff at the Space to receive the necessary training and authorization.</value>
</data>
<data name="MachinePage_CurrentUser" xml:space="preserve">
<value>Current User:</value>
</data>
<data name="MachinePage_ForceBlock" xml:space="preserve">
<value>Block Machine</value>
</data>
<data name="MachinePage_ForceDisable" xml:space="preserve">
<value>Disable Machine</value>
</data>
<data name="MachinePage_ForceFree" xml:space="preserve">
<value>Free Machine</value>
</data>
<data name="MachinePage_GiveBack" xml:space="preserve">
<value>GiveBack</value>
</data>
<data name="MachinePage_Identify" xml:space="preserve">
<value>Identify</value>
</data>
<data name="MachinePage_LastUser" xml:space="preserve">
<value>Last User:</value>
</data>
<data name="MachinePage_ManageMachine" xml:space="preserve">
<value>Manage Machine:</value>
</data>
<data name="MachinePage_OpenWiki" xml:space="preserve">
<value>Open Wiki</value>
</data>
<data name="MachinePage_Unlock" xml:space="preserve">
<value>Unlock</value>
</data>
<data name="MachinePage_Use" xml:space="preserve">
<value>Use</value>
</data>
<data name="MainPage_Build" xml:space="preserve">
<value>Build</value>
</data>
<data name="MainPage_Machines" xml:space="preserve">
<value>Machines</value>
</data>
<data name="MainPage_Profile" xml:space="preserve">
<value>My Profile</value>
</data>
<data name="MainPage_Servers" xml:space="preserve">
<value>Servers</value>
</data>
<data name="MainPage_Users" xml:space="preserve">
<value>Users</value>
</data>
<data name="MainPage_Version" xml:space="preserve">
<value>Version</value>
</data>
<data name="OK" xml:space="preserve">
<value>Ok</value>
</data>
<data name="OR" xml:space="preserve">
<value>or</value>
</data>
<data name="PASSWORD" xml:space="preserve">
<value>Password</value>
</data>
<data name="ProfilePage_ChangePassword" xml:space="preserve">
<value>Change Password</value>
</data>
<data name="ProfilePage_NewPassword" xml:space="preserve">
<value>New Password</value>
</data>
<data name="ProfilePage_OldPassword" xml:space="preserve">
<value>Old Password</value>
</data>
<data name="ProfilePage_UpdatePassword" xml:space="preserve">
<value>Update Password</value>
</data>
<data name="SCANQR" xml:space="preserve">
<value>Scan QR-Code</value>
</data>
<data name="ServerListPage_ActiveConnection" xml:space="preserve">
<value>Active Connection</value>
</data>
<data name="ServerListPage_ConnectToNewServer" xml:space="preserve">
<value>Connect to new Server</value>
</data>
<data name="ServerListPage_LastConnection" xml:space="preserve">
<value>Last Connections</value>
</data>
<data name="ServerPageModel_ConnectionFailed" xml:space="preserve">
<value>Connection failed</value>
</data>
<data name="ServerPage_Connect" xml:space="preserve">
<value>Connect</value>
</data>
<data name="ServerPage_DefaultText" xml:space="preserve">
<value>You can set a server as the default server and then the app will automatically connect to that server upon startup.</value>
</data>
<data name="ServerPage_Disconnect" xml:space="preserve">
<value>Disconnect</value>
</data>
<data name="ServerPage_IsDefault" xml:space="preserve">
<value>This connection has been set as the default and FabAccess will automatically connect to this server upon startup.</value>
</data>
<data name="ServerPage_SetDefault" xml:space="preserve">
<value>Set as Default Connection</value>
</data>
<data name="SetUpProcess_ScanPage_Button" xml:space="preserve">
<value>Login to your Space</value>
</data>
<data name="SetUpProcess_WelcomePage_Button" xml:space="preserve">
<value>Begin working</value>
</data>
<data name="SetUpProcess_WelcomePage_Text" xml:space="preserve">
<value>FabAccess is a machine management system designed for makerspaces, fablab and other collaborative workspaces.
With FabAccess, you can access and schedule machines, manage users and receive real-time updates on machine status and usage. The platform provides a decentralized solution for managing and connecting to machines across different Spaces, making it easier for users to collaborate and innovate together.</value>
</data>
<data name="SetUpProcess_WelcomePage_Title" xml:space="preserve">
<value>Welcome to FabAccess</value>
</data>
<data name="StartPage_Connecting" xml:space="preserve">
<value>Connecting to Server</value>
</data>
<data name="StartPage_Starting" xml:space="preserve">
<value>Starting App</value>
</data>
<data name="TITLE_AddUser" xml:space="preserve">
<value>Add User</value>
</data>
<data name="TITLE_ConnectToServer" xml:space="preserve">
<value>Connect to Server</value>
</data>
<data name="TITLE_Machine" xml:space="preserve">
<value>Machine</value>
</data>
<data name="TITLE_Machines" xml:space="preserve">
<value>Machines</value>
</data>
<data name="TITLE_Profile" xml:space="preserve">
<value>My Profile</value>
</data>
<data name="TITLE_Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="TITLE_Servers" xml:space="preserve">
<value>Servers</value>
</data>
<data name="TITLE_Settings" xml:space="preserve">
<value>Settings</value>
</data>
<data name="TITLE_User" xml:space="preserve">
<value>User</value>
</data>
<data name="TITLE_Users" xml:space="preserve">
<value>Users</value>
</data>
<data name="Uncategorised" xml:space="preserve">
<value>Uncategorised</value>
</data>
<data name="UserListPage_AddUser" xml:space="preserve">
<value>Add new User</value>
</data>
<data name="UserListPage_Search" xml:space="preserve">
<value>Search User</value>
</data>
<data name="UserListPage_SearchUser" xml:space="preserve">
<value>Search Username ...</value>
</data>
<data name="USERNAME" xml:space="preserve">
<value>Username</value>
</data>
<data name="UserPage_ChangePassword" xml:space="preserve">
<value>Update Password</value>
</data>
<data name="UserPage_CreateCard" xml:space="preserve">
<value>Create new FabFire Card</value>
</data>
<data name="UserPage_NewPassword" xml:space="preserve">
<value>New Password</value>
</data>
<data name="UserPage_UnbindCard" xml:space="preserve">
<value>Unbind FabFire Card</value>
</data>
<data name="UserPage_UpdatePassword" xml:space="preserve">
<value>Force Password Update</value>
</data>
<data name="VERSION" xml:space="preserve">
<value>Version</value>
</data>
<data name="YAY" xml:space="preserve">
<value>YAY</value>
</data>
</root>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -139,9 +139,15 @@
<value>Connect to Server</value> <value>Connect to Server</value>
</data> </data>
<data name="AddServerProcess_SelectServerPage_Info" xml:space="preserve"> <data name="AddServerProcess_SelectServerPage_Info" xml:space="preserve">
<value>FabAccess is a decentralized machine management system. Each Space thus uses its own server. <value>FabAccess is a decentralized machine management system, which means that it is designed to allow each Space to have its own dedicated server for managing its machines. If you want to connect to the FabAccess server for a specific Space, you will need to obtain the host address from that particular Space.
Ask your Space for the address of your server.
You can also put down several servers and then connect to the desired server.</value> In addition to being able to connect to individual servers, FabAccess also allows you to add multiple servers to your account. This feature is especially useful for makers and innovators who have access to machines at multiple Spaces.</value>
</data>
<data name="AddServerProcess_SelectServerPage_Placeholder" xml:space="preserve">
<value>test.fab-access.org</value>
</data>
<data name="AddServerProcess_SelectServerPage_TryConnection" xml:space="preserve">
<value>Trying to connect to the server</value>
</data> </data>
<data name="AddUserPage_AddUser" xml:space="preserve"> <data name="AddUserPage_AddUser" xml:space="preserve">
<value>Add User</value> <value>Add User</value>
@ -154,11 +160,11 @@ You can also put down several servers and then connect to the desired server.</v
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_AddUserFailed" xml:space="preserve"> <data name="ALERT_AddUserFailed" xml:space="preserve">
<value>Add User failed</value> <value>Add User failed.</value>
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_AuthFailed" xml:space="preserve"> <data name="ALERT_AuthFailed" xml:space="preserve">
<value>Authentication failed</value> <value>Authentication failed.</value>
<comment>Message Title</comment> <comment>Message Title</comment>
</data> </data>
<data name="ALERT_AuthServer" xml:space="preserve"> <data name="ALERT_AuthServer" xml:space="preserve">
@ -166,11 +172,11 @@ You can also put down several servers and then connect to the desired server.</v
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_BadMechanism" xml:space="preserve"> <data name="ALERT_BadMechanism" xml:space="preserve">
<value>SASL Mechanism is not supported-</value> <value>SASL Mechanism is not supported.</value>
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_ConnectionFailed" xml:space="preserve"> <data name="ALERT_ConnectionFailed" xml:space="preserve">
<value>Connection failed</value> <value>Connection failed.</value>
<comment>Message Title</comment> <comment>Message Title</comment>
</data> </data>
<data name="ALERT_ConnectionTimeout" xml:space="preserve"> <data name="ALERT_ConnectionTimeout" xml:space="preserve">
@ -185,6 +191,9 @@ You can also put down several servers and then connect to the desired server.</v
<value>Connection already exist. Please delete old Connection before adding the new Connection.</value> <value>Connection already exist. Please delete old Connection before adding the new Connection.</value>
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_ID" xml:space="preserve">
<value>ID is invalid.</value>
</data>
<data name="ALERT_PasswordInvalid" xml:space="preserve"> <data name="ALERT_PasswordInvalid" xml:space="preserve">
<value>Password is invalid.</value> <value>Password is invalid.</value>
<comment>Message Content</comment> <comment>Message Content</comment>
@ -194,7 +203,7 @@ You can also put down several servers and then connect to the desired server.</v
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_SASLAuth" xml:space="preserve"> <data name="ALERT_SASLAuth" xml:space="preserve">
<value>SASL Authenticaiton failed</value> <value>SASL Authentication failed</value>
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_TLSInvalid" xml:space="preserve"> <data name="ALERT_TLSInvalid" xml:space="preserve">
@ -210,7 +219,7 @@ You can also put down several servers and then connect to the desired server.</v
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_UserExist" xml:space="preserve"> <data name="ALERT_UserExist" xml:space="preserve">
<value>User allready exist.</value> <value>User already exist.</value>
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="ALERT_UsernameInvalid" xml:space="preserve"> <data name="ALERT_UsernameInvalid" xml:space="preserve">
@ -218,7 +227,7 @@ You can also put down several servers and then connect to the desired server.</v
<comment>Message Content</comment> <comment>Message Content</comment>
</data> </data>
<data name="Bionade" xml:space="preserve"> <data name="Bionade" xml:space="preserve">
<value>It's Bionade</value> <value>It's Bionade!</value>
</data> </data>
<data name="BUILD" xml:space="preserve"> <data name="BUILD" xml:space="preserve">
<value>Build</value> <value>Build</value>
@ -230,7 +239,7 @@ You can also put down several servers and then connect to the desired server.</v
<value>Confirm</value> <value>Confirm</value>
</data> </data>
<data name="ConnectionStatus_Connecting" xml:space="preserve"> <data name="ConnectionStatus_Connecting" xml:space="preserve">
<value>Connecting to Server ...</value> <value>Connecting to Server</value>
</data> </data>
<data name="ConnectionStatus_NoConnection" xml:space="preserve"> <data name="ConnectionStatus_NoConnection" xml:space="preserve">
<value>No Connection to Server</value> <value>No Connection to Server</value>
@ -245,7 +254,7 @@ You can also put down several servers and then connect to the desired server.</v
<value>Delete Server</value> <value>Delete Server</value>
</data> </data>
<data name="DIALOG_DeleteServerConfirm" xml:space="preserve"> <data name="DIALOG_DeleteServerConfirm" xml:space="preserve">
<value>"Do you really want to delete this Server?"</value> <value>Do you really want to delete this Server?</value>
</data> </data>
<data name="DIALOG_DeleteUser" xml:space="preserve"> <data name="DIALOG_DeleteUser" xml:space="preserve">
<value>Delete User</value> <value>Delete User</value>
@ -266,8 +275,8 @@ You can also put down several servers and then connect to the desired server.</v
<value>Machine</value> <value>Machine</value>
</data> </data>
<data name="MachinePage_CanNotUseByPermission" xml:space="preserve"> <data name="MachinePage_CanNotUseByPermission" xml:space="preserve">
<value>You do not have the authorization to use this machine. <value>You are not currently authorized to use this machine.
Ask in your Space if you can be trained on the machine to be unlocked for the machine.</value> Please speak with the staff at the Space to receive the necessary training and authorization.</value>
</data> </data>
<data name="MachinePage_CurrentUser" xml:space="preserve"> <data name="MachinePage_CurrentUser" xml:space="preserve">
<value>Current User:</value> <value>Current User:</value>
@ -284,6 +293,9 @@ Ask in your Space if you can be trained on the machine to be unlocked for the ma
<data name="MachinePage_GiveBack" xml:space="preserve"> <data name="MachinePage_GiveBack" xml:space="preserve">
<value>GiveBack</value> <value>GiveBack</value>
</data> </data>
<data name="MachinePage_Identify" xml:space="preserve">
<value>Identify</value>
</data>
<data name="MachinePage_LastUser" xml:space="preserve"> <data name="MachinePage_LastUser" xml:space="preserve">
<value>Last User:</value> <value>Last User:</value>
</data> </data>
@ -356,11 +368,14 @@ Ask in your Space if you can be trained on the machine to be unlocked for the ma
<data name="ServerPage_Connect" xml:space="preserve"> <data name="ServerPage_Connect" xml:space="preserve">
<value>Connect</value> <value>Connect</value>
</data> </data>
<data name="ServerPage_DefaultText" xml:space="preserve">
<value>You can set a server as the default server and then the app will automatically connect to that server upon startup.</value>
</data>
<data name="ServerPage_Disconnect" xml:space="preserve"> <data name="ServerPage_Disconnect" xml:space="preserve">
<value>Disconnect</value> <value>Disconnect</value>
</data> </data>
<data name="ServerPage_IsDefault" xml:space="preserve"> <data name="ServerPage_IsDefault" xml:space="preserve">
<value>Is Default Connection</value> <value>This connection has been set as the default and FabAccess will automatically connect to this server upon startup.</value>
</data> </data>
<data name="ServerPage_SetDefault" xml:space="preserve"> <data name="ServerPage_SetDefault" xml:space="preserve">
<value>Set as Default Connection</value> <value>Set as Default Connection</value>
@ -372,10 +387,12 @@ Ask in your Space if you can be trained on the machine to be unlocked for the ma
<value>Begin working</value> <value>Begin working</value>
</data> </data>
<data name="SetUpProcess_WelcomePage_Text" xml:space="preserve"> <data name="SetUpProcess_WelcomePage_Text" xml:space="preserve">
<value>Automate your Space with FabAccess</value> <value>FabAccess is a machine management system designed for makerspaces, fablab and other collaborative workspaces.
With FabAccess, you can access and schedule machines, manage users and receive real-time updates on machine status and usage. The platform provides a decentralized solution for managing and connecting to machines across different Spaces, making it easier for users to collaborate and innovate together.</value>
</data> </data>
<data name="SetUpProcess_WelcomePage_Title" xml:space="preserve"> <data name="SetUpProcess_WelcomePage_Title" xml:space="preserve">
<value>Welcome</value> <value>Welcome to FabAccess</value>
</data> </data>
<data name="StartPage_Connecting" xml:space="preserve"> <data name="StartPage_Connecting" xml:space="preserve">
<value>Connecting to Server</value> <value>Connecting to Server</value>
@ -417,7 +434,10 @@ Ask in your Space if you can be trained on the machine to be unlocked for the ma
<value>Uncategorised</value> <value>Uncategorised</value>
</data> </data>
<data name="UserListPage_AddUser" xml:space="preserve"> <data name="UserListPage_AddUser" xml:space="preserve">
<value>Add User</value> <value>Add new User</value>
</data>
<data name="UserListPage_Search" xml:space="preserve">
<value>Search User</value>
</data> </data>
<data name="UserListPage_SearchUser" xml:space="preserve"> <data name="UserListPage_SearchUser" xml:space="preserve">
<value>Search Username ...</value> <value>Search Username ...</value>
@ -428,9 +448,15 @@ Ask in your Space if you can be trained on the machine to be unlocked for the ma
<data name="UserPage_ChangePassword" xml:space="preserve"> <data name="UserPage_ChangePassword" xml:space="preserve">
<value>Update Password</value> <value>Update Password</value>
</data> </data>
<data name="UserPage_CreateCard" xml:space="preserve">
<value>Create new FabFire Card</value>
</data>
<data name="UserPage_NewPassword" xml:space="preserve"> <data name="UserPage_NewPassword" xml:space="preserve">
<value>New Password</value> <value>New Password</value>
</data> </data>
<data name="UserPage_UnbindCard" xml:space="preserve">
<value>Unbind FabFire Card</value>
</data>
<data name="UserPage_UpdatePassword" xml:space="preserve"> <data name="UserPage_UpdatePassword" xml:space="preserve">
<value>Force Password Update</value> <value>Force Password Update</value>
</data> </data>

View File

@ -13,7 +13,7 @@
<ContentView.Content> <ContentView.Content>
<StackLayout> <StackLayout>
<StackLayout IsVisible="{Binding IsBusy}"> <StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout> </StackLayout>
<StackLayout> <StackLayout>
@ -23,9 +23,10 @@
<Binding Path="IsConnected" Converter="{StaticResource InvertBoolConverter}"/> <Binding Path="IsConnected" Converter="{StaticResource InvertBoolConverter}"/>
</MultiBinding> </MultiBinding>
</StackLayout.IsVisible> </StackLayout.IsVisible>
<Label Text="{x:Static resource_text:TextResource.ConnectionStatus_NoConnection}"/> <Label Text="{x:Static resource_text:TextResource.ConnectionStatus_NoConnection}" Style="{StaticResource Style_Label_Text_Center}"/>
<Label Text="{x:Static resource_text:TextResource.ConnectionStatus_Connecting}" IsVisible="{Binding IsConnecting}"/> <Label Text="{x:Static resource_text:TextResource.ConnectionStatus_Connecting}" IsVisible="{Binding IsConnecting}" Style="{StaticResource Style_Label_Text_Center}"/>
<Label Text="{x:Static resource_text:TextResource.ConnectionStatus_NotConnected}" IsVisible="{Binding IsConnecting, Converter={StaticResource InvertBoolConverter}}"/> <ActivityIndicator IsRunning="{Binding IsConnecting}" IsVisible="{Binding IsConnecting}"/>
<Label Text="{x:Static resource_text:TextResource.ConnectionStatus_NotConnected}" IsVisible="{Binding IsConnecting, Converter={StaticResource InvertBoolConverter}}" Style="{StaticResource Style_Label_Text_Center}"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentView.Content> </ContentView.Content>

23
CHANGELOG.md Normal file
View File

@ -0,0 +1,23 @@
# Revision history for Borepin
## 0.3.11 -- 2023-03-17
Final INTERFACER Release
### Features
* improved API
* create and bind SmartCards to users
* improved UI
* brand and template UI with theme file
### Updates
* create DES-Fire Cards with FabFire-Protocol
* identify machines with NTAG
* unlock machines with electric locks
* search for users
* bind and unbind FabFire-Card to users
* reconnect to server if connection is lost
* autoconnect to server on client start
* improved feedback for users if client lost connection
## 0.3.5 -- 2022-07-12
Beta INTERFACER Release

View File

@ -323,7 +323,14 @@ namespace FabAccessAPI
{ {
if(!IsConnected && CanConnect) if(!IsConnected && CanConnect)
{ {
await Connect(ConnectionData).ConfigureAwait(false); try
{
await Connect(ConnectionData).ConfigureAwait(false);
}
catch(AuthenticationException)
{
await Disconnect().ConfigureAwait(false);
}
} }
} }
@ -346,7 +353,7 @@ namespace FabAccessAPI
SslStream sslStream = new SslStream(tcpstream, false, new RemoteCertificateValidationCallback(_RemoteCertificateValidationCallback)); SslStream sslStream = new SslStream(tcpstream, false, new RemoteCertificateValidationCallback(_RemoteCertificateValidationCallback));
try try
{ {
sslStream.ReadTimeout = 2000; sslStream.ReadTimeout = 5000;
sslStream.AuthenticateAsClient("bffhd"); sslStream.AuthenticateAsClient("bffhd");
sslStream.ReadTimeout = -1; sslStream.ReadTimeout = -1;
@ -376,7 +383,7 @@ namespace FabAccessAPI
try try
{ {
Task timeoutTask = Task.Delay(3000); Task timeoutTask = Task.Delay(5000);
tcprpcClient.Connect(connectionData.Host.Host, connectionData.Host.Port); tcprpcClient.Connect(connectionData.Host.Host, connectionData.Host.Port);
await await Task.WhenAny(tcprpcClient.WhenConnected, timeoutTask); await await Task.WhenAny(tcprpcClient.WhenConnected, timeoutTask);

@ -1 +1 @@
Subproject commit 19f20f5154f0eced6288ff56cac840025ee51da1 Subproject commit cde4677575f8e133ac764663e131c80fc891d545

View File

@ -1,4 +1,5 @@
using FabAccessAPI; using FabAccessAPI;
using NUnit.Framework;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -11,6 +12,7 @@ namespace FabAccessAPI_Test
public const int TESTSERVER_PORT = 59661; public const int TESTSERVER_PORT = 59661;
public const string PASSWORD = "secret"; public const string PASSWORD = "secret";
[TestCase("Testuser")]
public static ConnectionData CreateConnetionData(string username) public static ConnectionData CreateConnetionData(string username)
{ {
ConnectionData connectionData = new ConnectionData() ConnectionData connectionData = new ConnectionData()

View File

@ -1,86 +1,10 @@
Borepin # Borepin
===
# Building Borepin is the client application for using FabAccess. Borepin is written in C# with [Xamarin](https://dotnet.microsoft.com/apps/xamarin) for UI. We use [Prism Libary](https://prismlibrary.com/docs/xamarin-forms/Getting-Started.html) for MVVM and navigation managment.
## On Windows # Download
1. Install Visual Studio 2019
[download Visual Studio](https://visualstudio.microsoft.com/de/)
* with Xamarin
* with UWP
* with .NET Desktop
2. Install GTKSharp for Windows
[download GTKSharp](https://www.mono-project.com/download/stable/#download-win)
3. Install capnproto
3.1 If you have Chocolatey installed Please see [https://fab-access.org/download](https://fab-access.org/download) for all download and build options!
```shell
$ choco install capnproto
```
3.2 else you can download it from [here](https://capnproto.org/install.html) and add it to your PATH
4. Clone Borepin # Server
[download Borepin](https://gitlab.com/fabinfra/fabaccess/client) Yoh will find proper documentation for setting up your own BFFH FabAccess Server at [https://fab-access.org/install](https://fab-access.org/install)
6. Load Borepin
7. Build Borepin
If Step 5. Build Borepin is failing because of GTKSharp, it could help to restart your PC.
## Build GTK Project
1. Install mono
[download mono](https://www.mono-project.com/download/stable/#download-lin)
2. Install mono, gtk-sharp, msbuild, nuget, capnproto
1.1 Debian based
```shell
$ apt install mono-complete, gtk-sharp2, libcanberra-gtk-module, nuget, capnproto, git
```
1.2 ArchLinux based
```shell
$ pacman -S mono, mono-msbuild, gtk-sharp-2, nuget, capnproto
```
3. Update NuGet
```shell
$ nuget update -self
```
3. Clone Borepin
```shell
$ git clone https://gitlab.com/fabinfra/fabaccess/client.git --recurse-submodules
```
4. Build Borepin
```shell
$ cd client
$ nuget restore
$ msbuild -t:Borepin_GTK
```
4. Run Borepin
```shell
$ mono ./Borepin/Borepin.GTK/bin/Debug/Borepin.GTK.exe
```
You can also use Rider or monodevelop as an IDE for development on Borepin
## macOS / iOS
1. Install Visual Studio for Mac
2. Install capnproto
If you install capnp with Homebrew you may have to symlink the capnp binary into '/usr/local/bin', or bring it into your PATH another way.
3. Clone Borepin
```shell
$ git clone https://gitlab.com/fabinfra/fabaccess/client.git --recurse-submodules
```
4. Open in Visual Studio
5. Build
# UI
We use [Xamarin](https://dotnet.microsoft.com/apps/xamarin) for our UI Implementation.
## Frameworks
We use [Prism Libary](https://prismlibrary.com/docs/xamarin-forms/Getting-Started.html) for MVVM and navigation managment.
# Testing
We use [NUnit](https://nunit.org/) for testing.

2
external/NFC vendored

@ -1 +1 @@
Subproject commit e79b6aace26c8b362a5f450345a67ba700f06805 Subproject commit a6479be14e86add7a84b3a1a502608a665ec51f0

122
waydroid-installer.sh Executable file
View File

@ -0,0 +1,122 @@
#!/bin/bash
# This script installs FabAccess Borepin client to Linux using waydroid Android Emulator.
# This script must run as normal user, not as root. However, several commands require sudo permissions!
# If waydroid is already installed, it will try to update the image if a newer one is available
#
# Tested on
# - Fedora 41 @ 14.03.2025 (vmario891)
# - TuxedoOS 24.04 LTS (Debian based)/noble @ 14.03.2025 (vmario891)
# - Ubuntu 24.04 LTS noble @ 18.03.2025 (vmario891)
if [ "$EUID" -eq 0 ]
then echo "Please do not run as root"
exit 1
fi
echo -e "Elevating script for sudo permissions (please enter password, if asked) ..."
sudo echo
BOREPIN_RELEASES="https://gitlab.com/api/v4/projects/20862588/releases/"
echo -e "Getting releases ..."
curl --silent ${BOREPIN_RELEASES} | jq -r '.[]|.tag_name' | sed -e 's/v//'
LATEST_RELEASE=$(curl --silent ${BOREPIN_RELEASES} | jq -r '.[0]|.tag_name' | sed -e 's/release\/v//')
echo -e "\nLatest release: ${LATEST_RELEASE}"
if [ "$(grep -Ei 'debian|buntu|mint' /etc/*release)" ]; then
PACKMAN="apt-get"
PVENV="python3-venv"
curl -s https://repo.waydro.id | sudo bash > /dev/null
fi
# dnf/rpm based
if [ "$(grep -Ei 'fedora|redhat' /etc/*release)" ]; then
PACKMAN="dnf"
PVENV="python3-virtualenv"
fi
if command -v waydroid 2>&1 >/dev/null; then
echo "waydroid is already installed!"
HASWAYDROID="true"
else
HASWAYDROID="false"
fi
echo -e "Cloning github.com/casualsnek/waydroid_script for libhoudini ..."
git clone https://github.com/casualsnek/waydroid_script > /dev/null 2>&1
if [ ! -d waydroid_script ]; then
echo -e "Error cloning ..."
exit 1
fi
echo -e "Downloading Borepin APK ..."
BOREPIN_APK="org.fab_infra.fabaccess-Signed.apk"
wget --quiet https://gitlab.com/api/v4/projects/20862588/packages/generic/borepin/v$LATEST_RELEASE/$BOREPIN_APK
if [ ! -f $BOREPIN_APK ]; then
echo -e "Error downloading ..."
exit 1
fi
echo -e "Updating and installing packages ..."
if [ $PACKMAN == "apt" ]; then
sudo $PACKMAN update > /dev/null && sudo $PACKMAN upgrade -y
fi
#on Fedora installing a package automatically updates ...
sudo $PACKMAN install -y waydroid wl-clipboard python3-pip $PENV
echo -e "Installing pyclip ..."
sudo pip3 install pyclip --quiet --break-system-packages --root-user-action=ignore
if [ $HASWAYDROID == "false" ]; then
echo -e "Initializing waydroid. This may take a while ..."
sudo waydroid init --system_channel https://ota.waydro.id/system --vendor_channel https://ota.waydro.id/vendor --rom_type lineage --system_type VANILLA
elselse
sudo waydroid upgrade
fi
echo -e "Starting waydroid session (if not running yet)..."
waydroid status | grep STOPPED > /dev/null
if [ $? == 0 ]; then
waydroid session start &
fi
sleep 5 #waiting for it a while
waydroid status | grep RUNNING > /dev/null
if [ $? != 0 ]; then
echo -e "Error starting waydroid session..."
exit 1
fi
echo -e "Configuring waydroid ..."
waydroid prop set persist.waydroid.multi_windows true
if [ $? != 0 ]; then
echo -e "Error starting waydroid session..."
exit 1
fi
waydroid session stop
echo -e "Installing libhoudini ..."
python3 -m venv waydroid_script/venv
waydroid_script/venv/bin/pip3 install --upgrade pip --quiet
waydroid_script/venv/bin/pip3 install -r waydroid_script/requirements.txt --quiet
sudo waydroid_script/venv/bin/python3 waydroid_script/main.py --android-version 11 install libhoudini > /dev/null 2>&1
sudo rm -rf waydroid_script/ > /dev/null
sleep 5
echo -e "Installing Borepin ..."
sudo systemctl restart waydroid-container.service
waydroid session start &
sleep 5
waydroid app install $BOREPIN_APK
rm $BOREPIN_APK > /dev/null
sleep 5
echo -e "Starting Borepin ..."
waydroid app launch org.fab_infra.fabaccess &
sleep 5
echo -e "If Borepin does not appear, you can launch it from start menu (entry 'FabAccess') or by commandline: 'waydroid app launch org.fab_infra.fabaccess &'"