solidpod library

Support for flutter apps accessing solid PODs.

Copyright (C) 2024-2025, Software Innovation Institute, ANU.

Licensed under the MIT License (the "License").

License: https://choosealicense.com/licenses/mit/.

Authors: Graham Williams, Anushka Vidanage

Classes

AppInfo
AppInfo is class that stores the information of a particular app (i.e. the app that invokes methods of this class), including: name, version, canonical name, package name, build number.
AuthDataManager
AuthDataManager manages the Solid-OIDC authentication session:
BatchDeleteResult
Encapsulates the outcome of a batch delete operation on a Solid POD.
KeyManager
KeyManager is the main coordinator class to manage security key and encryption keys for data stored in PODs.
LogRecord
Data model for log record data in each log entry in the permission log in a Pod
Permission
Data model for parsing permission map of recipient into list of permission objects used in permission table.
PermissionDetails
Data model for permission details retrieved in GrantPermissionUi() from ACL file, and fetching ownerWebId and granterWebId if provided or deriving them.
PermissionHelper
Helper class for permission data operations.
PodAppKey
The verified key material for one app, derived once from its security key.
PodAppProfile
The display name, avatar, and privacy of one app's profile.
PodNotification
A single notification exchanged between two PODs.
PredicateBase
Abstract base for all predicate enums providing common functionality.
PublicSharingHooks
Hook points that let host applications layer additional content transformations on top of solidpod's own encrypted-TTL wrapper when files are shared with the Public or Authenticated User classes.
ResourceMetadata
SharedGroup
A named group of recipient WebIDs the user has shared a resource with.
SolidConstants
Organized structure for Solid-related constants.
WebIdCheckResult
Structured outcome of validateWebId.
ZipDownloadResult
Encapsulates the outcome of a batch zip download operation.

Enums

AccessMode
Mode of access to a resource
CommonAclPredicate
Pure Web Access Control predicates from http://www.w3.org/ns/auth/acl# For combined ACL predicates used in ACL file operations, see AclPredicate in web_acl.dart which includes predicates from multiple namespaces.
DcTermsPredicate
Dublin Core Terms predicates from http://purl.org/dc/terms/
EncryptionStatus
Outcome of checking whether a resource on a POD is encrypted by solidpod.
FileOpenMode
The mode in which a file is opened
FoafPredicate
FOAF (Friend of a Friend) predicates from http://xmlns.com/foaf/0.1/
PathType
PermissionLogLiteral
A class to represent permission log literals
RdfPredicate
Common RDF predicates from http://www.w3.org/1999/02/22-rdf-syntax-ns#
RecipientType
Type of recipient receiving access to a resource
ResourceContentType
Types of the content of resources
ResourceStatus
Enum of resource status
SIIPredicate
SII customised predicates
SolidFunctionCallStatus
Solid function call results
VcardPredicate
VCard predicates from http://www.w3.org/2006/vcard/ns#
WebIdCheckStatus
Outcome of validating a candidate WebID URL.
WebIdStatus
Outcome of validating that a URL points to a real Solid WebID profile document, as opposed to merely returning a 200 response. Plain existence is insufficient because many ordinary websites happily return 200 HTML for any unmatched path (SPA catch-alls, soft 404s, etc.), which would otherwise be mistaken for a valid WebID.
XsdDatatype
XML Schema datatypes from http://www.w3.org/2001/XMLSchema#

Constants

agentStr → const String
appsTerms → const String
Terms predicate
authUserPred → const String
dataDir → const String
demoWebID → const String
displayNameFile → const String
Display name resource. Always stored as linked data so that other apps and queries can interpret it via FOAF/VCard predicates.
foaf → const String
notificationDir → const String
permStr → const String
ACL file map strings
profCard → const String
String terms used as predicates in ttl files.
profileDir → const String
profilePictureFile → const String
Avatar resource. Stored as a turtle file so the same resource can hold either an unencrypted base64-wrapped image (when the user opts to make their profile public) or the encrypted form produced by writePod() (the default for an app using encryption).
terms → const String
whatIsWebID → const String
String variable for WebIDs

Properties

appDirName String
Length limit for long strings for a screen. Setup app data directory name
getter/setter pair
authenticatedAgent → URIRef
Allows access to any authenticated agent
final
authStateNotifier ValueNotifier<bool>
Global auth state notifier for reactive UI updates. Listen to this to get notified when login/logout happens.
final
publicAgent → URIRef
Two objects/values for predicate acl:agentClass foaf:Agent for public access acl:AutenticatedAgent for allowing access by authenticated agents Allows access to any agent, i.e., the public
final

Functions

appHasEncryption(String appRootUrl) Future<bool>
Whether the app folder at appRootUrl has encryption set up (i.e. an encryption/enc-keys.ttl file exists). When false the app stores only plaintext data and its profile can be edited without a security key.
applyPublicShareDecryptedHookInPlace(String fileUrl) Future<void>
Apply the PublicSharingHooks.onPublicShareDecrypted transformer to the current (already-plaintext) bytes of fileUrl and write back any resulting change.
cancelSolidAuthenticate() → void
Returns true while solidAuthenticate is awaiting the browser-based OAuth flow. Aborts any in-flight solidAuthenticate call. Delegates to solid_auth.cancelAuthenticate() which closes the local OAuth callback server and errors the pending awaiter, so this caller unwinds with a SolidAuthCancelledException.
changeCssAccountPassword({required String serverUrl, required String email, required String oldPassword, required String newPassword}) Future<void>
Changes the account password on a Community Solid Server (CSS v7+).
checkPodInitialization() Future<(bool, Map<String, dynamic>)>
Check if the user's POD structure is initialised.
checkResourceStatus(String resUrl, {bool isFile = true}) Future<ResourceStatus>
Asynchronously checks whether a given resource exists on the server.
checkWebIdProfile(String webIdUrl) Future<WebIdStatus>
Validate that webIdUrl points to a real Solid WebID profile document, not just any HTTP resource that happens to return 200.
chkExistsAndHasAcl({required String fileName, required bool isFile, bool isFileUrl = false, bool isExternalRes = false}) Future<SolidFunctionCallStatus>
Check fileName exists and has the associated ACL file. Requires user to be logged in.
cleanEncryptedFileName(String fileName) String
Strips the .enc.ttl suffix added by solidpod's encryption layer, restoring the original file name for display or download purposes.
clearPodStructureInitialised() Future<void>
Clears the initialisation flag, forcing a full structure check on the next login. Useful when the expected folder/file layout changes between app versions.
copySharedKeyUserClass(Key indKey, String resourceUrl, List permissionList, RecipientType recipientType) Future<void>
Copy shared individual key, either publicly or for all authenticated users
createContainer(String parentPath, String folderName, {bool createAcl = true}) Future<void>
Creates a new container (directory) on the POD from a relative path.
createCssAccount({required String serverUrl, required String email, required String password, String? podName}) Future<String?>
Creates a new account on a Community Solid Server (CSS v7+).
createDir(String dirUrl) Future<void>
Create a directory with the given URL.
createResource(String resourceUrl, {dynamic content = '', bool isFile = true, bool replaceIfExist = true, ResourceContentType contentType = ResourceContentType.turtleText}) Future<void>
Asynchronously creates a resource (a file or directory / container) on a server using HTTP requests:
deleteContainer(String parentPath, String folderName) Future<void>
Deletes a container (directory) and all of its contents recursively.
deleteDataFileDialog(String fileName, BuildContext context, {ResourceContentType contentType = ResourceContentType.turtleText}) Future<void>
Delete a data file (and its ACL file if exist), remove its individual key and the corresponding IV from the ind-key-file.
deleteExternalFile(String fileUrl, {ResourceContentType contentType = ResourceContentType.turtleText}) Future<void>
Delete an external file with path fileUrl and the shared key if the file is encrypted. Throws an exception if the file does not exist or any error occurs.
deleteFile({required String fileUrl, ResourceContentType contentType = ResourceContentType.turtleText, bool isKey = false, String? ownerWebId}) Future<void>
Delete a file and its associated resources, after first revoking external access to the file. The file with URL fileUrl, its ACL file, and its encryption key (if exists) will be deleted. The permission logs of any recipients to the file, will also be updated with a log line recording that permissions have been revoked. Throws an exception if the file does not exist or any error occurs.
deleteItems({required String parentPath, List<String> fileNames = const [], List<String> directoryNames = const [], void onProgress(int completed, int total)?}) Future<BatchDeleteResult>
Delete a mixed batch of files and directories from a Solid POD.
deleteLargeFile({required String remoteFilePath, String? ownerWebId, bool isPodRelativePath = false, void onProgress(int, int)?}) Future<void>
Delete a large file previously sent using writeLargeFile with URL remoteFilePath (relative to appname/data directory) in POD.
deleteLogIn() Future<bool>
Delete login information from the local storage.
deleteResource(String resourceUrl, ResourceContentType contentType) Future<void>
Delete a file or a directory
deleteSharedGroup(String name) Future<void>
Remove the saved group named name (case-insensitive) from the user's POD. Does nothing when no such group exists.
derivePairDisplayName(String? webId) String
Returns a human-readable label for the POD addressed by webId, used purely for UI surfacing (notification centre listings, error dialogs).
derivePairId(String? webId) String
Derive a stable, filename-safe identifier for the POD addressed by webId. The identifier is used to name the pair-specific notification file (e.g. notifications/<id>.json) and the corresponding encryption key file (encryption/notification-<id>.ttl).
downloadItemsAsZip({required String parentPath, List<String> fileNames = const [], List<String> directoryNames = const [], void onProgress(int completed, int total)?}) Future<ZipDownloadResult>
Download multiple files and/or directories from a Solid POD and bundle them into a single zip archive in memory.
extractRecipWebIdList(Map<String, dynamic> dataFilesMap, {List<String>? fileList}) List<String>
Extract the list of unique WebIds of recipients of the Pod user's files from the dataFilesMap containing acccess control lists for each file in the app data folder of the user's Pod. Where the first webId, on the unique WebId list aggregated across all their files, is assumed to be the user.
fetchNotifications() Future<List<PodNotification>>
Pull every notification visible to the currently logged-in user.
filenameToResourceUrl({required String fileName, bool isFile = true, bool isFileUrl = false, bool isExternalRes = false}) Future<String>
Get resource Url from a filename, with different options for how the filename is provided. If isExternalRes or isFileUrl is set to true, the filename is already the resource url and is returned unchanged.
genAclTurtle(String resourceUrl, {String externalWebId = '', bool isFile = true, Set<AccessMode> ownerAccess = const {AccessMode.read, AccessMode.write, AccessMode.control}, Set<AccessMode>? publicAccess, Set<AccessMode>? authUserAccess, Map<String, Set<AccessMode>>? thirdPartyAccess, Map<String, Set<AccessMode>>? groupAccess}) Future<String>
Generate TTL string for ACL file of a given resource
generateCustomFolders(List customFolderPaths) List<String>
Generates a list of custom folder paths for a given application.
generateDefaultFiles() Future<Map>
Generates a list of default folder paths for a given application.
generateDefaultFolders() Future<List<String>>
Generates a list of default folder paths for a given application.
getAccessMode(String mode) AccessMode
Return access mode based on a given String value
getAppNameVersion() Future<({String name, String version})>
Extract the app name and the version from the package info Return a record (with named fields https://dart.dev/language/records).
getAuthoriser({bool isExternalRes = false, bool isGranter = false, String? webId}) Future<String>
Standardise retrieval of authoriser (ownerWebId or granterWebId) for a resource in GrantPermissionUi
getDataDirPath() Future<String>
Returns the path of the data directory.
getDateTime(String dateTimeStr) String
Get date and time from a string
getDirUrl(String dirPath, {String? webId}) Future<String>
Create the URL for a directory (container)
getEncKeyPath() Future<String>
Returns the path of file with verification key and private key.
getFileEncryptionStatus(String filePath, {PathType pathType = PathType.relativeToData}) Future<EncryptionStatus>
Inspect the resource filePath on the POD and return a detailed EncryptionStatus describing whether it is encrypted by solidpod.
getFileUrl(String filePath, {String? webId}) Future<String>
Create the URL for a file
getLatestLog(Map logDataMap, [String? userWebId]) Map
Get latest log entries If need to exclude logs of files owned by a specific webid define userWebId.
getRecipientList() Future<List<String>>
Retrieve the list of recipients that have access to any file in the user's POD.
getRecipientType(String agentType, String receiverUri) RecipientType
Get agent types as a human readable string
getResource(String resourceUrl) Future<Uint8List>
Get the resource with URL resourceUrl from server. The resource could be a text, turtle, binary file. If resourceUrl ends with '/', i.e., a container / directory, This function returns the bytes of a turtle string representing the list of resources in the container / directory.
getResources() Future<List<String>>
Get the list of files created by the user in their POD by querying the data directory of the POD.
getResourcesInContainer(String containerUrl) Future<({List<String> files, List<String> subDirs})>
Get the list of sub-containers and files in a container Adapted from getContainerList() in gurriny/indi/lib/models/common/rest_api.dart
getSharedGroups() Future<List<SharedGroup>>
Read the list of previously used recipient groups from the user's POD.
getTokensForResource(String resourceUrl, String httpMethod) Future<({String accessToken, String dPopToken})>
Get tokens necessary to fetch a resource from a POD.
getWebId() Future<String?>
Return the web ID.
grantPermission({required String fileName, required List permissionList, required RecipientType recipientType, required List recipientWebIdList, required String ownerWebId, required String granterWebId, bool isFile = true, bool isExternalRes = false, String? groupName}) Future<SolidFunctionCallStatus>
Grant access permissions to fileName to the type of recipient or specific recipients, if recipient type is individual or group, and group or individual recipients specified. This action updates the ACL file of the resource in the owner's Pod, and appends a log entry to the permission log in the owner, granter and recipients POD.
initialStructureTest(List<String> folders, Map files) Future<List>
The fetchPrvFile function is an asynchronous function designed to fetch profile data from a specified URL profCardUrl. It takes three parameters: profCardUrl (the URL to fetch data from), accessToken (used for authorization), and dPopToken (another form of token used in headers for enhanced security). Tests the initial structure of a user's resources in a Solid Pod by checking the existence of specified folders and files.
initPod(String securityKey, {List<String>? dirUrls, List<String>? fileUrls}) Future<void>
Initialise the directory and file structure in a POD.
isContentEncrypted({required String fileUrl, required String content}) bool
Inspect raw Turtle content for solidpod's encryption markers.
isDir(String path) bool
Check if a given path string is a directory or not.
isFileEncrypted(String filePath, {PathType pathType = PathType.relativeToData}) Future<bool>
Check whether the resource filePath on the POD is encrypted by solidpod.
isPathInCurrentApp(String resourcePath) Future<bool>
Checks whether a POD-relative resourcePath falls within the current application's directory tree.
isPodStructureInitialised() Future<bool>
Returns true if the POD structure has already been initialised for the current user and app, allowing subsequent logins to skip the full folder/file existence check.
isUserLoggedIn() Future<bool>
Check whether a user is logged in or not.
isValidIpv4(String host) bool
Returns true when host is a syntactically valid IPv4 address: four dot-separated octets, each a decimal number in the range 0..255 with no leading sign and at most three digits.
logoutPod() Future<bool>
Logging out the user with comprehensive error handling and platform support
looksLikeIpv4Attempt(String host) bool
Returns true when host looks like an attempt to type an IPv4 literal, i.e. it only contains decimal digits and dots. This is intentionally permissive: malformed inputs such as 192, 192.168, 192.168.1, 1.2.3.4.5 and 256.0.0.1 all return true so callers can then reject them via isValidIpv4.
markPodStructureInitialised() Future<void>
Persists a flag indicating the POD structure has been successfully initialised for the current user and app.
permMapToList(Map map) List<Permission>
pickRedirectUri(List<String> uris) String
Selects the appropriate redirect URI from uris based on the runtime platform, using the URI format (and, on web, the origin) as the discriminator:
prewarmSolidAuthenticate(String serverId, {required String clientId, required List<String> redirectUris, List<String> postLogoutRedirectUris = const [], OidcPlatformSpecificOptions? oidcOptions}) Future<void>
Resolves serverId's issuer and initialises the underlying OIDC manager ahead of time, so a later solidAuthenticate call with the exact same serverId, clientId, redirectUris, and oidcOptions can skip straight to the browser redirect.
readAppProfile(String appRootUrl, {PodAppKey? key}) Future<PodAppProfile>
Read the profile (display name + avatar) of the app folder at appRootUrl.
readExternalPod(String fileUrl) Future<String>
Read fileUrl from an external POD.
readLargeFile({required String remoteFilePath, required String localFilePath, String? ownerWebId, bool isPodRelativePath = false, void onProgress(int, int)?}) Future<void>
Get a large file previously sent using writeLargeFile with name remoteFilePath (relative to appname/data directory) and save it to a local file with path localFilePath.
readLargeFileAsBytes({required String remoteFilePath, String? ownerWebId, bool isPodRelativePath = false, void onProgress(int, int)?}) Future<Uint8List>
Get a large file previously sent using writeLargeFile with name remoteFilePath (relative to appname/data directory) and return it as bytes.
readPermission({required String fileName, required bool isFile, bool isFileUrl = false, bool isExternalRes = false}) Future<Map>
Read permission given for the fileName from the associated ACL file.
readPermissionFileList({required List<String> fileList, bool isFile = true, bool isFilePath = false, bool isFileUrl = false}) Future<Map<String, dynamic>>
Read permissions of each file in a list of files, Note: the list of files are always files owned by the user.
readPod(String filePath, {PathType pathType = PathType.relativeToData, String? ownerWebId}) Future<String>
Read a (shared) file from POD..
readResMetadata(String filePath, {PathType pathType = PathType.relativeToData}) Future<ResourceMetadata>
registerLogoutCacheCallback(Future<void> callback()) → void
Register a callback to clear application-specific caches during logout. This callback will be invoked BEFORE the OAuth2 logout endpoint call, preventing race conditions where cached data might be visible during logout.
revokePermission({required String fileName, required List permissionList, required String recipientIndOrGroupWebId, required String ownerWebId, required String granterWebId, required RecipientType recipientType, bool isFile = true, bool isFileUrl = false, bool isExternalRes = false}) Future<SolidFunctionCallStatus>
Revoke permissions to fileName for a given individual or group Web ID recipientIndOrGroupWebId by removing the permission in the ACL within the owner's POD and adding a log entry recording the revoked permission in the permission logs of the owner, granter and recipient.
revokePermissionToDelFile({required String fileName, required bool isFileEncrypted, required List permissionList, required String recipientWebId, required String ownerWebId, required String granterWebId, bool isFileUrl = false}) Future<SolidFunctionCallStatus>
Revoke permissions to non-existent fileName (ie already deleted) for a given individual Web ID recipientWebId. Note: assumed for use case of user updating their own logs to revoke their access to an external file that has already been deleted without prior revoking of access to recipients. This is the case for files deleted before revoking permission was included in the delete process, or files deleted on the server.
saveSharedGroup(SharedGroup group) Future<void>
Save (insert or update) a recipient group in the user's POD.
sendNotification({required String recipientWebId, required String title, String? content, int priority = 0}) Future<void>
Send a notification to the POD identified by recipientWebId.
setAppDirName(String inputAppDirName) Future<void>
Set directory name for the app for storing the POD data.
setInheritKeyDir(String dirUrl, {bool createAcl = true}) Future<void>
Set a key for a given directory so that key can be used to encrypt multiple resources within the directory. Takes two input parameters dirUrl - URL of the directory createAcl - Whther to crete an acl file for the directory or not (default: true) Directory will be created if not exist
sharedResources([String? fileName, String? sourceWebId]) Future
Read permission given for the fileName.
sharedResourcesHistory({required String resourceName}) Future<List<LogRecord>>
Read permission log (including revoked permissions) of a user's Pod for a specific resourceName.
silentLogout() Future<bool>
Clear all login state without opening a browser.
solidAuthenticate(String serverId, BuildContext context, {required String clientId, required List<String> redirectUris, List<String> postLogoutRedirectUris = const [], OidcPlatformSpecificOptions? oidcOptions}) Future<List?>
Asynchronously authenticate a user against a Solid server serverId.
tripleMapToTurtle(Map<URIRef, Map<URIRef, dynamic>> triples, {Map<String, Namespace>? bindNamespaces}) String
Generate Turtle string from triples stored in a map: {subject: {predicate: {object}}}
tryRestoreSession() Future<List?>
Silently restores a previously saved login session without browser interaction.
turtleToTripleMap(String turtleStr) Map<String, Map<String, dynamic>>
Parse the Turtle string into triples stored in a map: {subject: {predicate: object(s)}
updateFileByQuery(String fileUrl, String query) Future<void>
Updates a file on the server with the provided SPARQL query.
validateContainerName(String folderName) → void
Validates that folderName is a safe container name.
validateWebId(String webId) Future<WebIdCheckResult>
Validate a candidate webId URL.
verifyAppSecurityKey(String appRootUrl, String securityKey) Future<PodAppKey>
Verify securityKey against the verification value stored in the app's encryption/enc-keys.ttl and return the derived PodAppKey.
verifySecurityKey(String securityKey, String verificationKey) bool
Verify the security key against a legacy (version 1) verification key.
writeAppProfile(String appRootUrl, {PodAppKey? key, String? displayName, Uint8List? avatarBytes, bool removeAvatar = false, required bool private}) Future<void>
Write the profile of the app folder at appRootUrl.
writeExternalPod(String fileUrl, String fileContent, String fileOwnerWebId, {bool encrypted = true, bool overwrite = true, String? inheritKeyFrom}) Future<void>
Write file fileUrl with content fileContent to an external PODs in the data directory (within potential subdirectories encoded in fileUrl). The content will be encrypted if the original content is true.
writeLargeFile({required String localFilePath, required String remoteFilePath, String? ownerWebId, String? inheritKeyFrom, bool createAcl = true, bool isPodRelativePath = false, void onProgress(int, int)?, bool encrypted = true}) Future<void>
Send a large local file with path localFilePath to a remote server using name remoteFilePath (relative to appname/data directory), encrypt the file content if encrypted is true.
writePod(String filePath, String fileContent, {bool encrypted = true, bool createAcl = true, bool overwrite = false, PathType pathType = PathType.relativeToData, String? inheritKeyFrom, String? ownerWebId}) Future<void>
Write filePath with content fileContent to POD in the data directory (within potential subdirectories encoded in filePath). fileContent will be encrypted by default.

Typedefs

PublicSharingContentTransformer = Future<String> Function(String resourceUrl, String content)
Signature of a transformer that rewrites the (plaintext) content of a resource as part of the public/authenticated-user sharing lifecycle.

Exceptions / Errors

AccessFailedException
AccessForbiddenException
AppEncryptionNotSetupException
Thrown when an app folder has no encryption/enc-keys.ttl, meaning the app has never set up encryption and therefore has no encrypted profile to read with a security key.
CssAccountApiNotSupportedException
Thrown by changeCssAccountPassword when the Solid server does not expose the Community Solid Server (CSS v7+) account management JSON API at /.account/ (e.g. NSS, ESS, or older CSS versions). Callers should inform the user that password changes are not supported on their server.
CssEmailAlreadyRegisteredException
Thrown by createCssAccount when the email address is already registered on the server. Callers should keep the dialog open and let the user choose a different email or navigate to the login screen.
CssWrongCredentialsException
Thrown by changeCssAccountPassword when the CSS account API rejects the given email/password combination (i.e. the credentials are wrong). Distinct from transient errors (network, server) so callers can keep the dialog open and let the user correct their input.
NotLoggedInException
RecipientNotReadyException
Thrown when a notification cannot be delivered because the recipient's Pod is not ready — either their WebID does not exist, they have not set up the app, or their notification folder has not yet been created.
ResourceNotDecryptableException
ResourceNotExistException
SecurityKeyNotAvailableException
SecurityKeyVerificationException
Thrown when a provided security key fails verification against the verification value stored on the POD (i.e. the key is wrong). Distinct from transient errors (network, missing file) so callers can decide to forget the stored security key only on a genuine mismatch.
SolidAuthCancelledException
Thrown by solidAuthenticate when the in-flight authentication is aborted by cancelSolidAuthenticate. Callers can catch this to distinguish a deliberate cancellation from a genuine authentication failure such as a network error.