This commit is contained in:
Paul Schneider 2026-02-14 16:54:27 +00:00
commit 45514010f2
3505 changed files with 154 additions and 523 deletions

View file

@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.Models.Account { 
public class ChangePasswordBindingModel {
[YaRequired]
[DataType(DataType.Password)]
public string OldPassword { get; set; }
[YaRequired]
[DataType(DataType.Password)]
public string NewPassword { get; set; }
}
public class SetPasswordBindingModel {
[YaRequired]
[DataType(DataType.Password)]
public string NewPassword { get; set; }
}
}

View file

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Abstract;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Account
{
public class ExternalLoginConfirmationViewModel
{
[YaRequired]
[YaStringLength(2,Constants.MaxUserNameLength)]
[YaRegularExpression(Constants.UserNameRegExp)]
public string Name { get; set; }
[YaRequired]
[EmailAddress]
public string Email { get; set; }
}
}

View file

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace Yavsc.ViewModels.Account
{
public class ForgotPasswordViewModel
{
[Required]
[StringLength(512)]
public string? LoginOrEmail { get; set; }
}
}

View file

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Account
{
// TODO external autentication providers
public class SignInModel
{
/// <summary>
/// Local user's name.
/// </summary>
/// <returns></returns>
[Required]
public string UserName { get; set; }
/// <summary>
/// Local user's password .
/// </summary>
/// <returns></returns>
[YaRequired]
[DataType(DataType.Password)]
public string Password { get; set; }
/// <summary>
/// When true, asks for a two-factor identification
/// </summary>
/// <returns></returns>
[Display(Name = "Se souvenir de moi?")]
public bool RememberMe { get; set; }
/// <summary>
/// Indicates the authentication provider'name chosen to authenticate,
/// contains "LOCAL" to choose the local application identity
/// and user password credentials.
/// </summary>
/// <returns></returns>
public string Provider { get; set; }
/// <summary>
/// This value does NOT indicate the OAuth client method recieving the code,
/// but the one called once authorized.
/// </summary>
/// <returns></returns>
public string ReturnUrl { get; set; }
}
public class YaAuthenticationDescription {
public string DisplayName { get; set; }
public string AuthenticationScheme { get; set; }
public IDictionary<string,object> Items { get; set; }
}
}

View file

@ -0,0 +1,41 @@
using Yavsc.Abstract.Identity;
namespace Yavsc.Models.Auth
{
public class Me : IApplicationUser {
public Me(string userId, string userName, string email, string avatar, ILocation address, string gCalId)
{
Id = userId;
UserName = userName;
EMail = email;
Avatar = avatar;
PostalAddress = address;
DedicatedGoogleCalendar = gCalId;
}
public string Id { get; set; }
public string UserName { get; set; }
public string EMail { get; set; }
public string[] Roles { get; set; }
/// <summary>
/// Known as profile, could point to an avatar
/// </summary>
/// <returns></returns>
public string Avatar { get; set; }
public IAccountBalance AccountBalance
{
get; set;
}
public string DedicatedGoogleCalendar
{
get; set;
}
public ILocation PostalAddress
{
get; set;
}
}
}

View file

@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Account
{
public class ResetPasswordViewModel
{
[Required]
public string Id { get; set; }
[Required]
public string Code { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Le {0} doit être long d'au moins {2} caractères.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirmer le mot de passe")]
[Compare("Password", ErrorMessage = "Le mot de passe et sa confirmation ne sont pas les mêmes.")]
public string ConfirmPassword { get; set; }
}
}

View file

@ -0,0 +1,11 @@
namespace Yavsc.ViewModels.Account
{
public class ShortUserInfo
{
public string Avatar { get; set; }
public string UserName { get; set; }
public string UserId { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Account
{
public class UnregisterViewModel
{
[Required]
public string UserId { get; set; }
public string? ReturnUrl { get; set; }
}
}

View file

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Account
{
public class VerifyCodeViewModel
{
[YaRequired]
public string Provider { get; set; }
[YaRequired]
public string Code { get; set; }
public string ReturnUrl { get; set; }
[Display(Name = "Se souvenir de ce navigateur?")]
public bool RememberMe { get; set; }
}
}

View file

@ -0,0 +1,11 @@
namespace Yavsc.ViewModels.Administration {
public class AdminViewModel {
public RoleInfo [] Roles { get; set; }
public int AdminCount { get; set; }
public bool YouAreAdmin { get; set; }
public int UserCount { get; set; }
}
}

View file

@ -0,0 +1,9 @@
namespace Yavsc.ViewModels.Administration
{
public class RoleInfo
{
public string Id { get; set; }
public string Name { get; set; }
public int UserCount { get; set; }
}
}

View file

@ -0,0 +1,15 @@
using Yavsc.Abstract.Identity;
namespace Yavsc.ViewModels.Administration
{
public class RoleUserCollection
{
public RoleUserCollection()
{
}
public string Id { get; set; }
public string Name { get; set; }
public UserInfo[] Users { get; set; }
}
}

View file

@ -0,0 +1,10 @@
namespace Yavsc.Models.Auth
{
public class AuthorisationView { 
public Scope[] Scopes { get; set; }
public string Message { get; set; }
}
}

View file

@ -0,0 +1,12 @@
namespace Yavsc {
public static class YavscClaimTypes {
public const string CircleMembership = "CircleMembership";
public const string GoogleUserId = "GoogleUserId";
}
}

View file

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth
{
public class DeletePermission: IAuthorizationRequirement
{
public DeletePermission()
{
}
}
}

View file

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth
{
public class EditPermission : IAuthorizationRequirement
{
public EditPermission()
{
}
}
}

View file

@ -0,0 +1,25 @@
using System.IO;
using Microsoft.AspNetCore.Authorization;
using Yavsc.Models.Blog;
namespace Yavsc.ViewModels.Auth {
public class FileSpotInfo : IAuthorizationRequirement
{
public DirectoryInfo PathInfo { get; private set; }
public FileSpotInfo(string path, BlogPost b) {
PathInfo = new DirectoryInfo(path);
AuthorId = b.AuthorId;
BlogEntryId = b.Id;
}
public string AuthorId { get; private set; }
public long BlogEntryId { get; private set; }
}
}

View file

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth
{
public class ModerationRequirement : IAuthorizationRequirement
{
public ModerationRequirement() {}
}
}

View file

@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth
{
public class PrivateChatEntryRequirement : IAuthorizationRequirement
{
}
}

View file

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth
{
public class ReadPermission: IAuthorizationRequirement
{
public ReadPermission()
{
}
}
}

View file

@ -0,0 +1,12 @@
using Microsoft.Extensions.FileProviders;
namespace Yavsc.ViewModels.Auth
{
public class ViewFileContext
{
public string UserName { get; set; }
public IFileInfo File { get; set; }
public string Path { get; set; }
}
}

View file

@ -0,0 +1,8 @@
namespace Yavsc.ViewModels
{
public class BasketView
{
public long HairCutActiveQueryCount { get; set; }
}
}

View file

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Access;
namespace Yavsc.ViewModels.Blog
{
public class BlogPostBase
{
[StringLength(1024)]
public string? Photo { get; set; }
[StringLength(1024)]
[Required]
public string Title { get; set; }
[StringLength(56224)]
public string? Content { get; set; }
[InverseProperty("Target")]
[Display(Name = "Liste de contrôle d'accès")]
public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; }
}
}

View file

@ -0,0 +1,50 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Models.Blog;
namespace Yavsc.ViewModels.Blog;
public class BlogPostCreateViewModel : BlogPostBase
{
public bool Publish { get; set; }
}
public class BlogPostEditViewModel : BlogPostCreateViewModel
{
[Required]
public required long Id { get; set; }
public BlogPostEditViewModel()
{
}
public static BlogPostEditViewModel From(BlogPost blogInput)
{
return new BlogPostEditViewModel
{
Id = blogInput.Id,
Title = blogInput.Title,
Publish = false,
Photo = blogInput.Photo,
Content = blogInput.Content,
ACL = blogInput.ACL
};
}
public static BlogPostEditViewModel FromViewModel(BlogPostEditViewModel blogInput)
{
return new BlogPostEditViewModel
{
Id = blogInput.Id,
Title = blogInput.Title,
Publish = false,
Photo = blogInput.Photo,
Content = blogInput.Content,
ACL = blogInput.ACL
};
}
}

View file

@ -0,0 +1,19 @@
using System;
using Yavsc.Models.Calendar;
using Yavsc.Server.Models.Calendar;
namespace Yavsc.ViewModels.Calendar
{
public class DateTimeChooserViewModel
{
public string InputId { get; set; }
public DateTime MinDate { get; set; }
public DateTime MaxDate { get; set; }
public Period [] Busy { get; set; }
public Period [] Free { get; set; }
public string [] FreeDates { get ; set; }
public string [] BusyDates { get ; set; }
}
}

View file

@ -0,0 +1,15 @@
using Google.Apis.Calendar.v3.Data;
namespace Yavsc.ViewModels.Calendar
{
public class SetGoogleCalendarViewModel
{
public string GoogleCalendarId { get; set; }
public string ReturnUrl { get; set; }
public CalendarList Calendars { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace Yavsc.ViewModels.Calendar {
public class UpcomingEventsViewModel {
}
}

View file

@ -0,0 +1,34 @@
//
// ChatHub.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// Copyright (c) 2016-2019 GNU GPL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System.Collections.Generic;
namespace Yavsc
{
public class ChatRoomInfo
{
public string Name;
public List<string> Users = new List<string>();
public List<string> Ops = new List<string>();
public List<string> Hops = new List<string>();
public string Topic;
}
}

View file

@ -0,0 +1,37 @@
using System.Collections.Generic;
using Yavsc.Models.Chat;
namespace Yavsc.ViewModels.Chat { 
public class ChannelShortInfo {
public string RoomName {get; set;}
public string Topic { get; set; }
}
public class ChatUserInfo : IChatUserInfo
{
public List<ChatConnection> Connections { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Avatar { get; set; }
public string[] Roles { get; set; }
}
public interface IChatUserInfo
{
List<ChatConnection> Connections { get; set; }
string UserId { get; set; }
string UserName { get; set; }
string Avatar { get; set; }
string[] Roles { get; set; }
}
}

View file

@ -0,0 +1,10 @@
namespace Yavsc.ViewModels.Controls
{
public class AjaxCheckBoxInfo
{
public string Text { get; set; }
public string Value { get; set; }
public bool Checked { get; set; }
}
}

View file

@ -0,0 +1,13 @@
namespace Yavsc.ViewModels.FrontOffice
{
public class FrontOfficeIndexViewModel
{
public int EstimateToProduceCount { get; set; }
public int EstimateToSignAsProCount { get; set; }
public int EstimateToSignAsCliCount { get; set; }
public int BillToSignAsProCount { get; set; }
public int BillToSignAsCliCount { get; set; }
public int NewPayementsCount { get; set; }
}
}

View file

@ -0,0 +1,38 @@
using System.Linq;
using Yavsc.Models.Workflow;
namespace Yavsc.ViewModels.FrontOffice
{
public partial class PerformerProfileViewModel
{
public string UserName { get; set; }
public string PerformerId { get; set; }
public bool Active { get; set; }
public bool AcceptNotifications { get; set; }
public bool AcceptPublicContact { get; set; }
public UserActivity Context { get; set; }
public object Settings { get; set; }
public UserActivity[] Extra { get; set; }
public string WebSite { get; set; }
public string SettingsClassName { get; set; }
public PerformerProfileViewModel(PerformerProfile profile, string activityCode, object settings)
{
UserName = profile.Performer.UserName;
PerformerId = profile.PerformerId;
Active = profile.Active;
AcceptNotifications = profile.AcceptNotifications;
AcceptPublicContact = profile.AcceptPublicContact;
Context = profile.Activity.FirstOrDefault(a => a.DoesCode == activityCode);
SettingsClassName = Context.Does.SettingsClassName;
Settings = settings;
WebSite = profile.WebSite;
Extra = profile.Activity.Where(a => a.DoesCode != activityCode).ToArray();
}
}
}

View file

@ -0,0 +1,7 @@
namespace Yavsc.ViewModels.Haircut
{
public class HaircutAdminViewModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Yavsc.ViewModels.Haircut
{
public class HaircutClientView
{
}
}

View file

@ -0,0 +1,7 @@
namespace Yavsc.ViewModels.Haircut
{
public class HaircutProviderView
{
}
}

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.FileSystem;
using Yavsc.Server.Helpers;
namespace Yavsc.ViewModels.Streaming
{
public class LiveCastClient
{
public string UserName { get; set; }
public WebSocket Socket { get; set; }
}
public class LiveEntryViewModel
{
public string UserName { get; set; }
public string FlowId { get; set; }
}
public class LiveCastHandler : IDisposable
{
public WebSocket Socket { get; set; }
public ConcurrentDictionary<string, WebSocket> Listeners { get; set; } = new ConcurrentDictionary<string, WebSocket>();
public CancellationTokenSource TokenSource { get; set; } = new CancellationTokenSource();
public void Dispose()
{
}
public async Task<FileReceivedInfo> ReceiveUserFile(ApplicationUser user, ILogger logger, string root, Queue<ArraySegment<byte>> queue, string destFileName, Func<bool> isEndOfInput)
{
// TODO lock user's disk usage for this scope,
// this process is not safe at concurrent access.
long usage = user.DiskUsage;
var item = new FileReceivedInfo
(root, AbstractFileSystemHelpers.FilterFileName(destFileName));
var fi = new FileInfo(Path.Combine(root, item.FileName));
if (fi.Exists)
{
item.Overridden = true;
usage -= fi.Length;
}
logger.LogInformation("Opening the file");
using (var dest = fi.Open(FileMode.Create, FileAccess.Write, FileShare.Read))
{
logger.LogInformation("Appening to file");
while (!isEndOfInput() || queue.Count > 0)
{
if (queue.Count > 0)
{
var buffer = queue.Dequeue();
logger.LogInformation($"writing {buffer.Count} bytes...");
await dest.WriteAsync(buffer.Array, buffer.Offset, buffer.Count);
logger.LogInformation($"done.");
usage += buffer.Count;
}
if (usage >= user.DiskQuota) break;
if (queue.Count == 0 && !isEndOfInput())
{
await Task.Delay(100);
}
}
user.DiskUsage = usage;
dest.Close();
}
if (usage >= user.DiskQuota)
{
item.QuotaOffense = true;
}
user.DiskUsage = usage;
return item;
}
}
}

View file

@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class AddPhoneNumberViewModel
{
[YaRequired]
[Phone]
[Display(Name = "Phone number")]
public string PhoneNumber { get; set; }
}
}

View file

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class ChangePasswordViewModel
{
[YaRequired]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[YaRequired]
[YaStringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
}

View file

@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class DoDirectCreditViewModel {
[YaRequired]
public string PaymentType  { get; set;}
[YaRequired]
public string PayerName  { get; set;}
[YaRequired]
public string FirstName  { get; set;}
[YaRequired]
public string LastName  { get; set;}
[YaRequired]
public string CreditCardNumber  { get; set;}
public string CreditCardType  { get; set;}
public string Cvv2Number  { get; set;}
public string CardExpiryDate  { get; set;}
public string IpnNotificationUrl { get; set; }
[YaRequired]
public string Street1 { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
[YaRequired]
public string PostalCode { get; set; }
public string Phone { get; set; }
[YaRequired]
public string CurrencyCode { get; set; }
[YaRequired]
public string Amount { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace Yavsc.ViewModels.Manage
{
public class FactorViewModel
{
public string Purpose { get; set; }
}
}

View file

@ -0,0 +1,18 @@
using Yavsc.Models;
namespace Yavsc.ViewModels.Manage
{
public class ProfileEMailUsageViewModel
{
public bool Allow { get; set; }
public ProfileEMailUsageViewModel()
{
}
public ProfileEMailUsageViewModel(ApplicationUser user=null)
{
Allow = user.AllowMonthlyEmail;
}
}
}

View file

@ -0,0 +1,8 @@
namespace Yavsc.ViewModels.Manage
{
public class RemoveLoginViewModel
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
}
}

View file

@ -0,0 +1,9 @@
using Yavsc.Models.Workflow;
namespace Yavsc.ViewModels.Manage
{
public class SetActivityViewModel : PerformerProfile
{
}
}

View file

@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class SetAddressViewModel
{
[YaRequired]
public string Street1 { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
[YaRequired]
public string PostalCode { get; set; }
}
}

View file

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class SetPasswordViewModel
{
[YaRequired]
[YaStringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
}

View file

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
using Yavsc.Attributes.Validation;
namespace Yavsc.ViewModels.Manage
{
public class VerifyPhoneNumberViewModel
{
[YaRequired]
public string Code { get; set; }
[YaRequired]
[Phone]
[Display(Name = "Phone number")]
public string PhoneNumber { get; set; }
}
}

View file

@ -0,0 +1,9 @@
namespace Yavsc.ViewModels
{
public enum OutputFormat {
Html,
LaTeX,
Pdf
}
}

View file

@ -0,0 +1,14 @@
using PayPal.PayPalAPIInterfaceService.Model;
using Yavsc.Models.Payment;
namespace Yavsc.ViewModels.PayPal
{
public class PaymentInfo
{
public PayPalPayment DbContent { get; set; }
public virtual GetExpressCheckoutDetailsResponseType DetailsFromPayPal { get; set; }
}
}

View file

@ -0,0 +1,16 @@
using Yavsc.Abstract.Identity.Security;
namespace Yavsc.ViewModels.Relationship
{
public class CirclesViewModel
{
public CirclesViewModel(ICircleAuthorized resource)
{
Target = resource;
if (resource!=null)
TargetTypeName = resource.GetType().Name;
}
public ICircleAuthorized Target { get; set; }
public string TargetTypeName { get; set; }
}
}

View file

@ -0,0 +1,9 @@
using System;
namespace Yavsc.ViewModels.Test
{
public class CalendarViewModel
{
public DateTime EventDate { get; set;}
}
}

View file

@ -0,0 +1,9 @@
using Yavsc.Models.Billing;
namespace Yavsc.ViewModels.Workflow
{
public class EstimateEdition
{
public Estimate Data { get; set; }
}
}

View file

@ -0,0 +1,11 @@
using Yavsc.Models.Workflow;
namespace Yavsc.ViewModels.Workflow
{
public class UserActivityViewModel
{
public UserActivity Declaration { get; set; }
public bool NeedsSettings { get; set; }
public IUserSettings Settings { get; set; }
}
}